¿Hay alguna manera de usar una clase Tuple, pero proporcione los nombres de los elementos que contiene?
Por ejemplo:
public Tuple<int, int, int int> GetOrderRelatedIds()
Eso devuelve los identificadores para OrderGroupId, OrderTypeId, OrderSubTypeId y OrderRequirementId.
Sería bueno que los usuarios de mi método sepan cuál es cuál. (Cuando llama al método, los resultados son result.Item1, result.Item2, result.Item3, result.Item4. No está claro cuál es cuál).
(Sé que podría crear una clase para contener todos estos ID, pero estos ID ya tienen sus propias clases en las que viven y hacer una clase para el valor de retorno de este método parece una tontería).
Tuple
es muy genérico, así que eso es todo lo que obtienesRespuestas:
En C # 7.0 (Visual Studio 2017) hay una nueva construcción para hacer eso:
fuente
List<(int first, int second)>
. Tuve que descargar el paquete System.ValueTuple de NuGet para que funcione en Visual Studio 2017.return (first: first, middle: middle, last: last);
return (first, middle, last);
en .NET 4.7.1 (no estoy seguro para 4.7.0)ValueTuple
, aunque generalmente son geniales, son un tipo de valor mutable (estructura), mientras queTuple
es un tipo de referencia inmutable (clase). Hasta donde sé, no hay forma de obtener un tipo de referenciaTuple
con nombres de elementos amigables.Hasta C # 7.0, no había manera de hacer esto menos que definir su propio tipo.
fuente
Aquí hay una versión demasiado complicada de lo que está preguntando:
¿Por qué no simplemente hacer una clase?
fuente
Tuple<T, T2>
no puedes ser una estructura.Con .net 4 quizás podría mirar
ExpandoObject
, sin embargo, no lo use para este caso simple, ya que lo que habrían sido errores en tiempo de compilación se convierten en errores en tiempo de ejecución.Algo más que vale la pena mencionar es un tipo anónimo dentro de un método , pero debe crear una clase si desea devolverlo.
fuente
Reproduciendo mi respuesta de esto publicación, ya que encaja mejor aquí.
A partir de C # v7.0, ahora es posible asignar un nombre a las propiedades de tupla que antes se usaban de forma predeterminada para nombres predefinidos como
Item1
,Item2
etc.Nombrando las propiedades de Tuple Literals :
La salida en la consola:
Devolver Tuple (que tiene propiedades con nombre) de un método :
La salida en la consola:
Crear una lista de tuplas con propiedades con nombre
Salida en consola:
Espero haberlo cubierto todo. En caso de que haya algo que me haya perdido, por favor envíeme un comentario en los comentarios.
Nota : Mis fragmentos de código utilizan la función de interpolación de cadenas de C # v7 como se detalla aquí .
fuente
MichaelMocko Respondido es genial,
pero quiero agregar algunas cosas que tuve que resolver
la línea anterior le dará un error de tiempo de compilación si está usando .net framework <4.7
Entonces, si tiene un proyecto que está usando .net framework <4.7 y aún desea usar ValueTuple, entonces workAround estaría instalando este paquete nuget
fuente
No, no puedes nombrar a los miembros de la tupla.
Lo intermedio sería usar ExpandoObject en lugar de Tuple.
fuente
Si los tipos de sus artículos son todos diferentes, aquí hay una clase que hice para obtenerlos de manera más intuitiva.
El uso de esta clase:
Código fuente:
fuente
Esto es muy molesto y espero que las futuras versiones de C # aborden esta necesidad. Creo que el trabajo más fácil es usar un tipo de estructura de datos diferente o cambiar el nombre de los "elementos" por su cordura y por la cordura de otros que leen su código.
fuente
Creo que crearía una clase pero otra alternativa son los parámetros de salida.
Como su Tupla solo contiene números enteros, puede representarlo con un
Dictionary<string,int>
pero tampoco lo recomiendo.
fuente
¿Por qué todos hacen la vida tan difícil? Las tuplas son para el procesamiento de datos bastante temporal . Trabajar con Tuples todo el tiempo hará que el código sea muy difícil de entender en algún momento. Creando clases para todo podría eventualmente inflar su proyecto.
Se trata de equilibrio, sin embargo ...
Su problema parece ser algo para lo que desearía una clase. Y solo por completar, esta clase a continuación también contiene constructores.
Este es el patrón apropiado para
O, si lo desea realmente simple: también puede usar inicializadores de tipo:
fuente
Escribiría los nombres de los Elementos en el resumen ... así que al pasar el cursor sobre la función helloworld () el texto dirá hola = Elemento1 y mundo = Elemento2
fuente
Solo para agregar a la respuesta @MichaelMocko. Las tuplas tienen un par de trampas en este momento:
No puede usarlos en árboles de expresión EF
Ejemplo:
Esto no se compilará con el error "Un árbol de expresiones no puede contener un literal de tupla". Desafortunadamente, la API de árboles de expresión no se expandió con soporte para tuplas cuando se agregaron al lenguaje.
Rastree (y vote) este problema para las actualizaciones: https://github.com/dotnet/roslyn/issues/12897
Para solucionar el problema, primero puede convertirlo a tipo anónimo y luego convertir el valor a tupla:
Otra opción es usar ValueTuple.Create:
Referencias
https://www.damirscorner.com/blog/posts/20181207-NoSupportForTuplesInExpressionTrees.html
Convierta el tipo anónimo al nuevo tipo de tupla C # 7
No puedes deconstruirlos en lambdas
Hay una propuesta para agregar el soporte: https://github.com/dotnet/csharplang/issues/258
Ejemplo:
Referencias
No se serializarán bien
Los nombres de campo de tupla solo están disponibles en tiempo de compilación y se borran por completo en tiempo de ejecución.
Referencias
fuente
Puedes escribir una clase que contenga la Tupla.
Debe anular las funciones Equals y GetHashCode
y los operadores == y! =.
volverá:
Cierto
Cierto
fuente
Ejemplo de tupla C # 7
fuente