2010-06-22 8 views
92

Estoy viendo la nueva característica C# de tuplas. Tengo curiosidad, ¿qué problema fue la tupla diseñada para resolver?¿Qué requisito fue diseñado para resolver la tupla?

¿Para qué has usado las tuplas en tus aplicaciones?

actualización

Gracias por las respuestas hasta el momento, déjame ver si tengo las cosas claras en mi mente. Se ha señalado un buen ejemplo de una tupla como coordenadas. ¿Esto se ve bien?

var coords = Tuple.Create(geoLat,geoLong); 

A continuación, utilice la tupla de este modo:

var myLatlng = new google.maps.LatLng("+ coords.Item1 + ", "+ coords.Item2 + "); 

¿Es eso correcto?

+3

posible duplicado de [? tuplas está utilizando en mi .NET 4.0 Código una mala decisión Diseño] (http://stackoverflow.com/questions/3017352/is-using-tuples-in-my-net-4-0-code-a-poor-design-decision) –

+4

Bueno, puedo pensar en dos respuestas ... –

+13

Si el concepto de "coordinar" hace Sentir como una clase entonces yo lo haría una clase. Use tuplas para aquellas situaciones donde * * no existe algún concepto razonable de "lógica de negocios" para el conjunto de datos que justifica la creación de un tipo. –

Respuesta

117

Al escribir programas, es muy común querer agrupar lógicamente un conjunto de valores que no tienen suficiente en común para justificar la creación de una clase.

Muchos lenguajes de programación le permiten lógicamente agrupar un conjunto de valores de otro modo no relacionado sin crear un tipo de una sola manera:

void M(int foo, string bar, double blah) 

Lógicamente, esto es exactamente lo mismo que un M método que toma un argumento que es una 3-tupla de int, string, double. Pero espero que en realidad no lo haga:

class MArguments 
{ 
    public int Foo { get; private set; } 
    ... etc 

a menos que MArguments tuviera algún otro significado en la lógica comercial.

El concepto de "agrupar un montón de datos no relacionados en alguna estructura que sea más liviana que una clase" es útil en muchos lugares, no solo para listas de parámetros de métodos formales. Es útil cuando un método tiene dos cosas que devolver, o cuando quiere sacar un diccionario de dos datos en lugar de uno, y así sucesivamente.

Los lenguajes como F # que admiten tipos de tupla proporcionan una gran flexibilidad para sus usuarios; son un conjunto extremadamente útil de tipos de datos. El equipo de BCL decidió trabajar con el equipo de F # para estandarizar en un tipo de tupla para el marco de modo que cada idioma se pueda beneficiar de ellos.

Sin embargo, en este punto no hay idioma compatible con tuplas en C#. Las tuplas son solo otro tipo de datos como cualquier otra clase de marco; no hay nada especial acerca de ellos. Estamos considerando agregar un mejor soporte para tuplas en versiones hipotéticas futuras de C#. Si alguien tiene alguna idea sobre el tipo de características que implican tuplas que le gustaría ver, me gustaría compartirlas con el equipo de diseño. Los escenarios realistas son más convincentes que las reflexiones teóricas.

+0

Información excelente. Todavía no puedo pensar en un buen escenario para usar tuplas en mis aplicaciones, pero entiendo mejor el concepto ahora. ¡Gracias! – Chaddeus

+0

Muy interesante para ver el comienzo de la convergencia del lenguaje entre C# y F #. ¿Podrían aparecer cosas como 'Asynch.Parallel' en versiones hipotéticas futuras de C#? – MalcomTucker

+1

@MalcomTucker: Asícrona y el paralelismo definitivamente están en nuestras mentes como áreas ricas donde las herramientas de lenguaje podrían usarse para resolver problemas reales. No creo que los flujos de trabajo asincrónicos estilo F # sean necesariamente los mejores para C#, pero definitivamente son inspiradores. –

9

A menudo es útil tener un tipo de "pareja", que solo se usa en situaciones rápidas (como devolver dos valores de un método). Las tuplas son una parte central de los lenguajes funcionales como F #, y C# los recogió en el camino.

+0

Gracias, actualicé la pregunta con más detalles ... – Chaddeus

+0

System.Web.UI tiene una clase Pair http://msdn.microsoft.com/en-us/library/system.web.ui.pair.aspx. – StingyJack

5

muy útil para el retorno de dos valores de una función

+1

como una estructura entonces? – KevinDTimm

+1

¿Tal vez para envolver un tipo anónimo? – bloparod

+1

Los veo como estructuras anónimas –

0

encuentro la refrescante KeyValuePair en C# para iterar sobre los pares de valores clave en un diccionario.

+0

'KeyValuePair' se puede ver como una solución de propósito especial. En Python, iterar sobre un 'dict' solo devuelve tuplas (clave, valor). – dan04

+0

Sí, como Python. :-) No sabía que KeyValuePair en C# no era una tupla? – Jubal

1

Una Tuple se usa a menudo para devolver múltiples valores de funciones cuando no desea crear un tipo específico. Si está familiarizado con Python, Python lo ha tenido durante mucho tiempo.

1

Un uso común puede ser evitar la creación de clases/estructuras que solo contengan 2 campos, en su lugar se crea un Tuple (o un KeyValuePair por ahora). útil como un valor de retorno, evitar la transmisión N cabo params ...

12

Se proporciona una alternativa a ref o out si tiene un método que tiene que devolver varios objetos nuevos como parte de su respuesta.

También le permite usar un tipo incorporado como tipo de retorno si todo lo que necesita hacer es mezclar dos o tres tipos existentes, y no desea tener que agregar una clase/estructura solo para esta combinación. (¿Alguna vez deseó que una función devolviera un tipo anónimo? Esta es una respuesta parcial a esa situación.)

+0

Gracias, esa es una buena explicación. – Chaddeus

+0

Maldita sea. Bonito. Desearía haber comprobado qué, tuplas, hace unos años;). – sabiland

1

Devolviendo más de un valor de una función. getCoordinates() no es muy útil si solo devuelve x o y o z, pero hacer una clase completa y un objeto para contener tres ints también parece bastante pesado.

22

Tuplas proporcionar una implementación inmutable de una colección

Aparte de los usos comunes de tuplas:

  • a valores comunes de grupo juntos sin tener que crear una clase
  • a devolver múltiples valores desde una función/método
  • etc ...

Los objetos inmutables son seguros hilo inherentemente:

Los objetos inmutables pueden ser útiles en aplicaciones de subprocesos múltiples. Varios hilos pueden actuar sobre datos representados por objetos inmutables sin preocuparse de que otros hilos modifiquen los datos. Por lo tanto, se considera que los objetos inmutables son más seguros para subprocesos que los objetos mutables.

De "Immutable Object" en la wikipedia

+0

Gracias por agregar información adicional a la pregunta. Muy apreciado. – Chaddeus

+0

Si desea una colección inmutable, debe usar una colección inmutable, no una Tuple. La diferencia es que para la mayoría de las colecciones inmutables no es necesario especificar el número de elementos en tiempo de compilación –

+0

@ BlueRaja-DannyPflughoeft Cuando escribí esta respuesta, las clases de colecciones inmutables de C# todavía no estaban disponibles en el BCL. Supongo que cambiaré 'colección' a 'objeto' ya que MS castró la implementación Tuple en C# –

0

me encontré con este punto de referencia performanve entre tuplas y pares de valores clave y probablemente tou lo encontrarán interesante. En resumen, dice que Tuple tiene ventaja porque es un calss, por lo tanto, se almacena en el montón y no en la pila, y cuando se pasa como argumento, su puntero es lo único que va. Pero KeyValuePair es una estructura por lo que es más rápido de asignar, pero es más lento cuando se usa.

http://www.dotnetperls.com/tuple-keyvaluepair

0

Su realmente votos, mientras Devolución de valores de funciones. Podemos recuperar múltiples valores y esto es bastante ahorrador en algunos escenarios.

4

Personalmente, considero que Tuples es una parte iterativa del desarrollo cuando estás en un ciclo de investigación, o simplemente "jugando". Como una Tuple es genérica, tiendo a pensar en ella cuando trabajo con parámetros genéricos, especialmente cuando quiero desarrollar una pieza genérica de código, y estoy comenzando en el extremo del código, en lugar de preguntarme "¿cómo me gustaría esta llamada? ¿mirar?".

A menudo me doy cuenta de que la colección que los formularios Tuple se vuelven parte de una lista, y mirando a Lista> realmente no expresa la intención de la lista, o cómo funciona. A menudo "vivo" con eso, pero me encuentro con la necesidad de manipular la lista y cambiar un valor, y en ese momento, no necesariamente quiero crear una nueva Tuple para eso, así que necesito crear mi propia clase o estructura. para sostenerlo, entonces puedo agregar código de manipulación.

Por supuesto, siempre hay métodos de extensión, pero con frecuencia no desea extender ese código adicional a las implementaciones genéricas.

Hubo ocasiones en que quería expresar datos como Tuple, y no tenía Tuples disponibles. (VS2008) en cuyo caso acabo de crear mi propia clase Tuple, y no la hago segura (inmutable).

Así que supongo que soy de la opinión de que las tuplas son programación perezosa a expensas de perder un nombre tipo que describe su propósito. El otro gasto es que debe declarar la firma de la Tupla donde sea que se use como parámetro. Después de una serie de métodos que comienzan a verse hinchados, puedes sentir lo mismo que yo, que vale la pena hacer una clase, ya que limpia las firmas del método.

Tiendo a comenzar teniendo la clase como miembro público de la clase en la que ya está trabajando. Pero en el momento en que se extiende más allá de simplemente una colección de valores, obtiene su propio archivo, y lo saco de la clase contenedora

En retrospectiva, creo que uso Tuples cuando no quiero irme y escribir una clase, y solo quiero pensar sobre lo que estoy escribiendo en este momento. Lo que significa que la firma de la tupla puede cambiar bastante en el texto media hora mientras descubro qué datos voy a necesitar para este método, y cómo devuelve los valores que devolverá.

Si tengo la oportunidad de refactorizar el código, entonces a menudo voy a cuestionar el lugar de un Tuple en él.

1

Pregunta anterior desde 2010, y ahora en 2017 Dotnet cambia y se vuelve más inteligente.

C# 7 introduce soporte de idiomas para tuplas, lo que permite nombres semánticos para los campos de una tupla usando tipos de tuplas nuevos y más eficientes.

En vs 2017 y .Net 4.7 (o la instalación de Nuget System.ValueTuple paquete), puede crear/usar una tupla de una manera muy eficaz y sencilla:

 var person = (Id:"123", Name:"john"); //create tuble with two items 
    Console.WriteLine($"{person.Id} name:{person.Name}") //access its fields 

Volviendo más de un valor de una método:

public (double sum, double average) ComputeSumAndAverage(List<double> list) 
    { 
     var sum= list.Sum(); 
     var average = sum/list.Count; 
     return (sum, average); 
    } 

    How to use: 

     var list=new List<double>{1,2,3}; 
     var result = ComputeSumAndAverage(list); 
     Console.WriteLine($"Sum={result.sum} Average={result.average}");  

Para más detalles lea: https://docs.microsoft.com/en-us/dotnet/csharp/tuples

Cuestiones relacionadas