que - ¿Qué es el análogo C#de C++ std:: pair?
typedef struct c++ (14)
Además de las clases personalizadas o las tuplas .Net 4.0, desde C # 7.0 hay una nueva característica llamada ValueTuple, que es una estructura que se puede usar en este caso. En lugar de escribir:
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
y acceda 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);
Estoy interesado: ¿Cuál es el análogo de C # de std::pair
en C ++? Encontré la clase System.Web.UI.Pair
, pero preferiría algo basado en plantillas.
¡Gracias!
Algunas respuestas parecen equivocadas,
- no se puede usar el diccionario, cómo se almacenan los pares (a, b) y (a, c). El concepto de pares no debe confundirse con la búsqueda asociativa de claves y valores
- Gran parte del código anterior parece sospechoso
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));
}
}
C # tiene Tuples partir de la versión 4.0.
Creé una implementación en 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.
Dependiendo de lo que quiera lograr, es posible que desee probar KeyValuePair .
Por supuesto, el hecho de no poder cambiar la clave de una entrada se puede corregir simplemente reemplazando la entrada completa por una nueva instancia de KeyValuePair.
Desafortunadamente, no hay ninguno. Puede usar 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.
Desde .NET 4.0 tienes clase System.Tuple<T1, T2>
:
// pair is implicitly typed local variable (method scope)
var pair = System.Tuple.Create("Current century", 21);
La biblioteca de PowerCollections (anteriormente disponible en Wintellect pero ahora alojada en Codeplex @ http://powercollections.codeplex.com ) tiene una estructura de par genérica.
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 estos pares encadenados:
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 produce:
test
12
true
Normalmente extiendo la clase Tuple
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 usalo asi
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 añadir:
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.
Si se trata de diccionarios y similares, está buscando System.Collections.Generic.KeyValuePair <TKey, TValue>.
System.Web.UI
contenía la clase Pair
porque se usaba mucho en ASP.NET 1.1 como una estructura interna de ViewState.
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 estructura System.ValueTuple
.
//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
han sido 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);