Estoy interesado: ¿Cuál es el análogo de std::pair
C # en C ++? Encontré System.Web.UI.Pair
clase, pero preferiría algo basado en plantillas.
¡Gracias!
Estoy interesado: ¿Cuál es el análogo de std::pair
C # en C ++? Encontré System.Web.UI.Pair
clase, pero preferiría algo basado en plantillas.
¡Gracias!
Respuestas:
Las tuplas están disponibles desde .NET4.0 y admiten genéricos:
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
En versiones anteriores puede usar System.Collections.Generic.KeyValuePair<K, V>
o una solución como la siguiente:
public class Pair<T, U> {
public Pair() {
}
public Pair(T first, U second) {
this.First = first;
this.Second = second;
}
public T First { get; set; }
public U Second { get; set; }
};
Y úsalo así:
Pair<String, int> pair = new Pair<String, int>("test", 2);
Console.WriteLine(pair.First);
Console.WriteLine(pair.Second);
Esto produce:
test
2
O incluso este par encadenado:
Pair<Pair<String, int>, bool> pair = new Pair<Pair<String, int>, bool>();
pair.First = new Pair<String, int>();
pair.First.First = "test";
pair.First.Second = 12;
pair.Second = true;
Console.WriteLine(pair.First.First);
Console.WriteLine(pair.First.Second);
Console.WriteLine(pair.Second);
Eso da salida:
test
12
true
Tuple
. Por lo tanto, puede decir Tuple.Create("Hello", 4)
cuál es un poco más fácil que new Tuple<string, int>("Hello", 4)
. (Por cierto, .NET4.0 ya está aquí desde 2010.)
Tuple<>
implementa una semántica sólida Equals
y GetHashCode
con valor, lo cual es genial. Tenga en cuenta al implementar sus propias tuplas.
System.Web.UI
contenía la Pair
clase porque se usaba mucho en ASP.NET 1.1 como una estructura ViewState interna.
Actualización de agosto de 2017: C # 7.0 / .NET Framework 4.7 proporciona una sintaxis para declarar una Tupla con elementos con nombre utilizando la System.ValueTuple
estructura.
//explicit Item typing
(string Message, int SomeNumber) t = ("Hello", 4);
//or using implicit typing
var t = (Message:"Hello", SomeNumber:4);
Console.WriteLine("{0} {1}", t.Message, t.SomeNumber);
ver MSDN para más ejemplos de sintaxis.
Actualización de junio de 2012: Tuples
forma parte de .NET desde la versión 4.0.
Aquí hay un artículo anterior que describe la inclusión en .NET4.0 y el soporte para genéricos:
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
tuple.Item1 = 4;
Lamentablemente, no hay ninguno. Puede usar el System.Collections.Generic.KeyValuePair<K, V>
en muchas situaciones.
Alternativamente, puede usar tipos anónimos para manejar tuplas, al menos localmente:
var x = new { First = "x", Second = 42 };
La última alternativa es crear una clase propia.
Algunas respuestas parecen simplemente incorrectas
Aquí está mi clase de pareja
public class Pair<X, Y>
{
private X _x;
private Y _y;
public Pair(X first, Y second)
{
_x = first;
_y = second;
}
public X first { get { return _x; } }
public Y second { get { return _y; } }
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (obj == this)
return true;
Pair<X, Y> other = obj as Pair<X, Y>;
if (other == null)
return false;
return
(((first == null) && (other.first == null))
|| ((first != null) && first.Equals(other.first)))
&&
(((second == null) && (other.second == null))
|| ((second != null) && second.Equals(other.second)));
}
public override int GetHashCode()
{
int hashcode = 0;
if (first != null)
hashcode += first.GetHashCode();
if (second != null)
hashcode += second.GetHashCode();
return hashcode;
}
}
Aquí hay un código de prueba:
[TestClass]
public class PairTest
{
[TestMethod]
public void pairTest()
{
string s = "abc";
Pair<int, string> foo = new Pair<int, string>(10, s);
Pair<int, string> bar = new Pair<int, string>(10, s);
Pair<int, string> qux = new Pair<int, string>(20, s);
Pair<int, int> aaa = new Pair<int, int>(10, 20);
Assert.IsTrue(10 == foo.first);
Assert.AreEqual(s, foo.second);
Assert.AreEqual(foo, bar);
Assert.IsTrue(foo.GetHashCode() == bar.GetHashCode());
Assert.IsFalse(foo.Equals(qux));
Assert.IsFalse(foo.Equals(null));
Assert.IsFalse(foo.Equals(aaa));
Pair<string, string> s1 = new Pair<string, string>("a", "b");
Pair<string, string> s2 = new Pair<string, string>(null, "b");
Pair<string, string> s3 = new Pair<string, string>("a", null);
Pair<string, string> s4 = new Pair<string, string>(null, null);
Assert.IsFalse(s1.Equals(s2));
Assert.IsFalse(s1.Equals(s3));
Assert.IsFalse(s1.Equals(s4));
Assert.IsFalse(s2.Equals(s1));
Assert.IsFalse(s3.Equals(s1));
Assert.IsFalse(s2.Equals(s3));
Assert.IsFalse(s4.Equals(s1));
Assert.IsFalse(s1.Equals(s4));
}
}
Si se trata de diccionarios y similares, está buscando System.Collections.Generic.KeyValuePair <TKey, TValue>.
Dependiendo de lo que desee lograr, es posible que desee probar KeyValuePair .
El hecho de que no pueda cambiar la clave de una entrada puede, por supuesto, rectificarse simplemente reemplazando la entrada completa por una nueva instancia de KeyValuePair.
Creé una implementación C # de Tuples, que resuelve el problema genéricamente entre dos y cinco valores: aquí está la publicación del blog , que contiene un enlace a la fuente.
Estaba haciendo la misma pregunta justo ahora, después de un rápido google, descubrí que hay una clase de pares en .NET, excepto que está en System.Web.UI ^ ~ ^ (http://msdn.microsoft.com/en-us/library/system.web.ui.pair.aspx ) Dios sabe por qué lo pusieron allí en lugar del marco de colecciones
Desde .NET 4.0 tienes System.Tuple<T1, T2>
clase:
// pair is implicitly typed local variable (method scope)
var pair = System.Tuple.Create("Current century", 21);
Normalmente extiendo la Tuple
clase a mi propio contenedor genérico de la siguiente manera:
public class Statistic<T> : Tuple<string, T>
{
public Statistic(string name, T value) : base(name, value) { }
public string Name { get { return this.Item1; } }
public T Value { get { return this.Item2; } }
}
y úsalo así:
public class StatSummary{
public Statistic<double> NetProfit { get; set; }
public Statistic<int> NumberOfTrades { get; set; }
public StatSummary(double totalNetProfit, int numberOfTrades)
{
this.TotalNetProfit = new Statistic<double>("Total Net Profit", totalNetProfit);
this.NumberOfTrades = new Statistic<int>("Number of Trades", numberOfTrades);
}
}
StatSummary summary = new StatSummary(750.50, 30);
Console.WriteLine("Name: " + summary.NetProfit.Name + " Value: " + summary.NetProfit.Value);
Console.WriteLine("Name: " + summary.NumberOfTrades.Value + " Value: " + summary.NumberOfTrades.Value);
Para que funcione lo anterior (necesitaba un par como clave de un diccionario). Tuve que agregar:
public override Boolean Equals(Object o)
{
Pair<T, U> that = o as Pair<T, U>;
if (that == null)
return false;
else
return this.First.Equals(that.First) && this.Second.Equals(that.Second);
}
y una vez que hice eso también agregué
public override Int32 GetHashCode()
{
return First.GetHashCode() ^ Second.GetHashCode();
}
para suprimir una advertencia del compilador.
La biblioteca PowerCollections (anteriormente disponible en Wintellect pero ahora alojada en Codeplex @ http://powercollections.codeplex.com ) tiene una estructura genérica de pares.
Además de la clase personalizada o .Net 4.0 Tuples, desde C # 7.0 hay una nueva característica llamada ValueTuple, que es una estructura que se puede utilizar en este caso. En lugar de escribir:
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
y acceder a los valores a través de t.Item1
y t.Item2
, simplemente puede hacerlo así:
(string message, int count) = ("Hello", 4);
o incluso:
(var message, var count) = ("Hello", 4);