Was ist C # analog von C ++ std :: pair?
-
03-07-2019 - |
Frage
Ich bin interessiert: Was C # 's analog von std::pair
in C ++ ist? Ich fand System.Web.UI.Pair
Klasse, aber ich würde etwas Template-basierte bevorzugen.
Danke!
Lösung
sind seit .NET4 verfügbar. 0 und Unterstützung Generika:
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
In früheren Versionen Sie System.Collections.Generic.KeyValuePair<K, V>
oder eine Lösung wie folgt verwendet werden:
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; }
};
Und es wie folgt verwendet werden:
Pair<String, int> pair = new Pair<String, int>("test", 2);
Console.WriteLine(pair.First);
Console.WriteLine(pair.Second);
Diese Ausgänge:
test
2
oder sogar unter gekettet Paare:
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);
Das Ausgänge:
test
12
true
Andere Tipps
System.Web.UI
enthielt die Pair
Klasse, weil sie stark in ASP.NET 1.1 als interne Struktur Viewstate verwendet wurde.
Update August 2017: C # 7.0 / .NET Framework 4.7 bietet eine Syntax, um ein Tuple mit benannten Elementen mit dem System.ValueTuple
struct.
//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);
finden Sie unter MSDN für weitere Syntaxbeispiele.
Update Juni 2012: Tuples
ist ein Teil von .NET seit Version 4.0.
Hier ist einen früheren Artikel beschreibt Einbeziehung in.NET4.0 und Unterstützung für Generika:
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
Leider gibt es keine. Sie können die System.Collections.Generic.KeyValuePair<K, V>
in vielen Situationen verwendet werden.
Alternativ können Sie anonyme Typen verwenden Tupel zu handhaben, zumindest lokal:
var x = new { First = "x", Second = 42 };
Die letzte Alternative ist es, eine eigene Klasse zu erstellen.
C # hat Tupeln ab Version 4.0.
Einige Antworten scheinen nur falsch,
- Sie können nicht Wörterbuch verwenden, wie die Paare speichern würde (a, b) und (a, c). Paare Konzept soll nicht mit assoziativem Look von Schlüsseln und Werten verwechselt wird
- Viele der oben genannten Code scheint suspekt
Hier ist mein Paar Klasse
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;
}
}
Hier finden Sie einige Testcode:
[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));
}
}
Wenn es um Wörterbücher und dergleichen, die Sie suchen System.Collections.Generic.KeyValuePair
Je nachdem, was Sie erreichen möchten, können Sie ausprobieren KeyValuePair .
Die Tatsache, dass Sie nicht den Schlüssel eines Eintrags kann natürlich durch einfaches Austauschen der gesamten Eintrag durch eine neue Instanz von KeyValuePair behoben werden ändern können.
ich eine C # -Implementierung von Tupeln erstellt, die das Problem allgemein zwischen zwei und fünf Werten lösen - hier ist die Blog-Post , die einen Link zur Quelle enthält.
Ich habe die gleiche Frage gerade jetzt nach einer schnellen Google fragen fand ich, dass es ein Paar Klasse in .NET außer seine im System.Web.UI ^ ~ ^ ( http://msdn.microsoft.com/en-us/library/system.web.ui.pair.aspx ) Gott weiß, warum sie hat es dort anstelle der Sammlungen Rahmen
Da .NET 4.0 Sie System.Tuple<T1, T2>
Klasse haben:
// pair is implicitly typed local variable (method scope)
var pair = System.Tuple.Create("Current century", 21);
ich in der Regel die Tuple
Klasse in meine eigene Generika-Wrapper wie folgt erweitern:
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; } }
}
und verwenden Sie es wie folgt:
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);
Auf Um die oben an der Arbeit (ich brauchte ein Paar als Schlüssel eines Wörterbuchs). Ich hatte hinzuzufügen:
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);
}
und einmal habe ich, dass ich auch hinzugefügt
public override Int32 GetHashCode()
{
return First.GetHashCode() ^ Second.GetHashCode();
}
eine Compiler-Warnung zu unterdrücken.
Die PowerCollections Bibliothek (früher von Wintellect aber jetzt auf Codeplex gehostet @ http://powercollections.codeplex.com ) hat eine generische Paar Struktur.
Neben benutzerdefinierter Klasse oder .Net 4.0 Tupeln, da C # 7.0 gibt es eine neue Funktion namens ValueTuple, die eine Struktur ist, die in diesem Fall verwendet werden können. Statt zu schreiben:
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
und Zugangswerte durch t.Item1
und t.Item2
, können Sie einfach tun es wie folgt aus:
(string message, int count) = ("Hello", 4);
oder auch:
(var message, var count) = ("Hello", 4);