significado - ¿Cuál es la mejor manera de usar un par(triple, etc.) de valores como un valor en C#?
para que sirve int en c++ (16)
Clases Builtin
En ciertos casos específicos, el .NET Framework ya proporciona clases similares a una tupla que puede aprovechar.
Pares y triples
La clase genérica System.Collections.Generic.KeyValuePair podría usar como una implementación de par adhoc. Esta es la clase que el diccionario genérico usa internamente.
Alternativamente, es posible que pueda conformarse con la estructura System.Collections.DictionaryEntry que actúa como un par rudimentario y tiene la ventaja de estar disponible en mscorlib. En el lado negativo, sin embargo, es que esta estructura no está fuertemente tipada.
Los pares y triples también están disponibles en forma de las clases System.Web.UI.Pair y System.Web.UI.Triplet . Aunque estas clases viven en el ensamblado System.Web , podrían ser perfectamente adecuadas para el desarrollo de winforms. Sin embargo, estas clases tampoco están fuertemente tipadas y podrían no ser adecuadas en algunos escenarios, como un marco de referencia general o una biblioteca.
Tuplas de orden superior
Para tuplas de orden superior, aparte de rodar su propia clase, puede que no haya una solución simple.
Si ha instalado el lenguaje F # , puede hacer referencia al archivo FSharp.Core.dll que contiene un conjunto de clases genéricas inmutables de Microsoft.Fsharp.Core.Tuple hasta sextuples genéricos. Sin embargo, aunque se puede redistribuir un FSharp.Code.dll no modificado, F # es un lenguaje de investigación y un trabajo en progreso, por lo que es probable que esta solución sea de interés solo en círculos académicos.
Si no desea crear su propia clase y no se siente cómodo al hacer referencia a la biblioteca F #, un ingenioso truco podría consistir en extender la clase genérica KeyValuePair para que el miembro Value sea en sí mismo un KeyValuePair anidado.
Por ejemplo, el siguiente código ilustra cómo puede aprovechar KeyValuePair para crear Triples:
int id = 33;
string description = "This is a custom solution";
DateTime created = DateTime.Now;
KeyValuePair<int, KeyValuePair<string, DateTime>> triple =
new KeyValuePair<int, KeyValuePair<string, DateTime>>();
triple.Key = id;
triple.Value.Key = description;
triple.Value.Value = created;
Esto permite extender la clase a cualquier nivel arbitrario según sea necesario.
KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string> quadruple =
new KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string>();
KeyValuePair<KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string>, string> quintuple =
new KeyValuePair<KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string>, string>, string>();
Rollo propio
En otros casos, es posible que deba recurrir a rodar su propia clase de tupla, y esto no es difícil.
Puedes crear estructuras simples como estas:
struct Pair<T, R>
{
private T first_;
private R second_;
public T First
{
get { return first_; }
set { first_ = value; }
}
public R Second
{
get { return second_; }
set { second_ = value; }
}
}
Marcos y Bibliotecas
Este problema se ha abordado anteriormente y existen marcos de propósito general. A continuación se muestra un enlace a uno de esos marcos:
Es decir, me gustaría tener una tupla de valores.
El caso de uso en mi mente:
Dictionary<Pair<string, int>, object>
o
Dictionary<Triple<string, int, int>, object>
¿Hay tipos incorporados como Pair o Triple? ¿O cuál es la mejor manera de implementarlo?
Actualización Hay algunas implementaciones de tuplas de uso general descritas en las respuestas, pero para las tuplas utilizadas como claves en los diccionarios, también debe verificar el cálculo correcto del código hash. Más información sobre eso en otra question .
Actualización 2 Supongo que también vale la pena recordar que cuando usa algún valor como clave en el diccionario, debe ser inmutable.
Avance rápido hasta 2010, .NET 4.0 ahora admite n-tuplas de n arbitrario . Estas tuplas implementan igualdad estructural y comparación como se esperaba.
Implementé una biblioteca de tuplas en C #. Visite http://www.adventuresinsoftware.com/generics/ y haga clic en el enlace "tuplas".
NGenerics: la popular biblioteca .Net de algoritmos y estructuras de datos, ha introducido recientemente estructuras de datos inmutables al conjunto.
Los primeros inmutables en implementar fueron las clases de par y tupla . El código está bien cubierto con pruebas y es bastante elegante. Puedes consultarlo here . Están trabajando en las otras alternativas inmutables en este momento y deberían estar listas en breve.
No hay clases integradas para eso. Puede usar System.Collections.Generic.KeyValuePair o implementar su propia implementación.
No hay entradas integradas, pero una clase Pair <T, R> es trivial de crear.
Normalmente solo creo mi propia estructura, que contiene los valores. A menudo es un poco más legible;)
Pair y Triplet son clases existentes en .net ver msdn:
Recientemente me encontré con ellos, mientras jugaba con la descodificación de viewstate
Para el primer caso, suelo usar
Dictionary<KeyValuePair<string, int>, object>
Podría usar System.Collections.Generic.KeyValuePair como implementación de su par.
O simplemente puedes implementar los tuyos, no son difíciles:
public class Triple<T, U, V>
{
public T First {get;set;}
public U Second {get;set;}
public V Third {get;set;}
}
Por supuesto, algún día puede encontrarse con un problema que Triple (string, int, int) no es compatible con Triple (int, int, string). Tal vez vaya con System.Xml.Linq.XElement en su lugar.
Puedes crear tus propias clases de tupla de manera relativamente fácil, lo único que puede complicarte es la igualdad y las anulaciones de hashcode (esenciales si vas a utilizarlas en diccionarios).
Cabe señalar que la KeyValuePair<TKey,TValue>
tiene métodos relativamente lentos de igualdad y hashcode .
Suponiendo que no le preocupe, todavía existe el problema de que el código termina siendo difícil de descifrar:
public Tuple<int, string, int> GetSomething()
{
//do stuff to get your multi-value return
}
//then call it:
var retVal = GetSomething();
//problem is what does this mean?
retVal.Item1 / retVal.Item3;
//what are item 1 and 3?
En la mayoría de estos casos, me resulta más fácil crear una clase de registro específica (al menos hasta que C # 4 haga que este compilador sea mágico)
class CustomRetVal {
int CurrentIndex { get; set; }
string Message { get; set; }
int CurrentTotal { get; set; }
}
var retVal = GetSomething();
//get % progress
retVal.CurrentIndex / retVal.CurrentTotal;
Sí, está System.Web.UI.Pair y System.Web.UI.Triplet (que tiene un creador sobrecargado para el comportamiento de tipo par).
También están los tipos Tuple <> en F #; solo necesita hacer referencia a FSharp.Core.dll.
Una solución simple no se ha mencionado aún. También puede usar una List<T>
. Está integrado, es eficiente y fácil de usar. Por supuesto, parece un poco raro al principio, pero hace su trabajo perfectamente, especialmente para un conteo más grande de elementos.
KeyValuePair es la mejor clase para ampliar si no desea crear sus propias clases.
int id = 33;
string description = "This is a custom solution";
DateTime created = DateTime.Now;
KeyValuePair<int, KeyValuePair<string, DateTime>> triple =
new KeyValuePair<int, KeyValuePair<string, DateTime>>();
triple.Key = id;
triple.Value.Key = description;
triple.Value.Value = created;
Puede extenderlo a tantos niveles como desee.
KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string, string> quadruple =
new KeyValuePair<KeyValuePair<KeyValuePair<string, string>, string, string>();
Nota : Las clases Triplet y Pair existen dentro de System.Web -dll, por lo que no es muy adecuado para otras soluciones aparte de ASP.NET.
public struct Pair<T1, T2>
{
public T1 First;
public T2 Second;
}
public struct Triple<T1, T2, T3>
{
public T1 First;
public T2 Second;
public T3 Third;
}