Je suis intéressé: Quel est l'analogue de C # std::pair
en C ++? J'ai trouvé la System.Web.UI.Pair
classe, mais je préfère quelque chose basé sur un modèle.
Je vous remercie!
Je suis intéressé: Quel est l'analogue de C # std::pair
en C ++? J'ai trouvé la System.Web.UI.Pair
classe, mais je préfère quelque chose basé sur un modèle.
Je vous remercie!
Réponses:
Les tuples sont disponibles depuis .NET4.0 et prennent en charge les génériques:
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
Dans les versions précédentes, vous pouvez utiliser System.Collections.Generic.KeyValuePair<K, V>
une solution comme celle-ci:
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; }
};
Et utilisez-le comme ceci:
Pair<String, int> pair = new Pair<String, int>("test", 2);
Console.WriteLine(pair.First);
Console.WriteLine(pair.Second);
Cela produit:
test
2
Ou même ces paires enchaînées:
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);
Cela génère:
test
12
true
Tuple
. Par conséquent, vous pouvez dire Tuple.Create("Hello", 4)
ce qui est un peu plus facile que new Tuple<string, int>("Hello", 4)
. (Au fait, .NET4.0 est déjà là depuis 2010.)
Tuple<>
implémentez une sémantique solide Equals
et GetHashCode
de valeur, ce qui est génial. Gardez à l'esprit lorsque vous implémentez vos propres tuples.
System.Web.UI
contenait la Pair
classe car elle était largement utilisée dans ASP.NET 1.1 en tant que structure ViewState interne.
Mise à jour d'août 2017: C # 7.0 / .NET Framework 4.7 fournit une syntaxe pour déclarer un tuple avec des éléments nommés à l'aide de la System.ValueTuple
structure.
//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);
voir MSDN pour plus d'exemples de syntaxe.
Mise à jour de juin 2012: Tuples
fait partie de .NET depuis la version 4.0.
Voici un article antérieur décrivant l'inclusion dans.NET4.0 et la prise en charge des génériques:
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
tuple.Item1 = 4;
Malheureusement, il n'y en a pas. Vous pouvez utiliser le System.Collections.Generic.KeyValuePair<K, V>
dans de nombreuses situations.
Alternativement, vous pouvez utiliser des types anonymes pour gérer les tuples, au moins localement:
var x = new { First = "x", Second = 42 };
La dernière alternative consiste à créer une propre classe.
Certaines réponses semblent fausses,
Voici ma classe de paire
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;
}
}
Voici un code de test:
[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));
}
}
S'il s'agit de dictionnaires et similaires, vous recherchez System.Collections.Generic.KeyValuePair <TKey, TValue>.
Selon ce que vous souhaitez accomplir, vous pouvez essayer KeyValuePair .
Le fait que vous ne pouvez pas modifier la clé d'une entrée peut bien sûr être corrigé en remplaçant simplement l'entrée entière par une nouvelle instance de KeyValuePair.
J'ai créé une implémentation C # de Tuples, qui résout le problème de manière générique entre deux et cinq valeurs - voici le billet de blog , qui contient un lien vers la source.
Je posais la même question tout à l'heure après un rapide google, j'ai trouvé qu'il y a une classe de paires dans .NET, sauf dans System.Web.UI ^ ~ ^ (http://msdn.microsoft.com/en-us/library/system.web.ui.pair.aspx ) Dieu sait pourquoi ils l'ont mis là au lieu du cadre des collections
Depuis .NET 4.0, vous avez une System.Tuple<T1, T2>
classe:
// pair is implicitly typed local variable (method scope)
var pair = System.Tuple.Create("Current century", 21);
J'étends généralement la Tuple
classe dans mon propre wrapper générique comme suit:
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; } }
}
et l'utiliser comme ça:
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);
Afin de faire fonctionner ce qui précède (j'avais besoin d'une paire comme clé d'un dictionnaire). J'ai dû ajouter:
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);
}
et une fois que j'ai fait ça, j'ai aussi ajouté
public override Int32 GetHashCode()
{
return First.GetHashCode() ^ Second.GetHashCode();
}
pour supprimer un avertissement du compilateur.
La bibliothèque PowerCollections (auparavant disponible chez Wintellect mais maintenant hébergée sur Codeplex @ http://powercollections.codeplex.com ) a une structure de paire générique.
Outre la classe personnalisée ou les tuples .Net 4.0, depuis C # 7.0, il existe une nouvelle fonctionnalité appelée ValueTuple, qui est une structure qui peut être utilisée dans ce cas. Au lieu d'écrire:
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
et accéder aux valeurs via t.Item1
et t.Item2
, vous pouvez simplement le faire comme ça:
(string message, int count) = ("Hello", 4);
ou même:
(var message, var count) = ("Hello", 4);