Ich habe eine Frage zu Union
und Concat
. Ich denke, beide verhalten sich im Falle von gleich List<T>
.
var a1 = (new[] { 1, 2 }).Union(new[] { 1, 2 }); // O/P : 1 2
var a2 = (new[] { 1, 2 }).Concat(new[] { 1, 2 }); // O/P : 1 2 1 2
var a3 = (new[] { "1", "2" }).Union(new[] { "1", "2" }); // O/P : "1" "2"
var a4 = (new[] { "1", "2" }).Concat(new[] { "1", "2" }); // O/P : "1" "2" "1" "2"
Das obige Ergebnis wird erwartet,
Aber falls List<T>
ich das gleiche Ergebnis bekomme .
class X
{
public int ID { get; set; }
}
class X1 : X
{
public int ID1 { get; set; }
}
class X2 : X
{
public int ID2 { get; set; }
}
var lstX1 = new List<X1> { new X1 { ID = 10, ID1 = 10 }, new X1 { ID = 10, ID1 = 10 } };
var lstX2 = new List<X2> { new X2 { ID = 10, ID2 = 10 }, new X2 { ID = 10, ID2 = 10 } };
var a5 = lstX1.Cast<X>().Union(lstX2.Cast<X>()); // O/P : a5.Count() = 4
var a6 = lstX1.Cast<X>().Concat(lstX2.Cast<X>()); // O/P : a6.Count() = 4
Aber beide verhalten sich gleich List<T>
.
Irgendwelche Vorschläge bitte?
Antworten:
Union gibt
Distinct
Werte zurück. Standardmäßig werden Referenzen von Elementen verglichen. Ihre Artikel haben unterschiedliche Referenzen, daher werden sie alle als unterschiedlich angesehen. Wenn Sie in einen Basistyp umwandelnX
, wird die Referenz nicht geändert.Wenn Sie überschreiben
Equals
undGetHashCode
(zur Auswahl bestimmter Elemente verwendet), werden Elemente nicht anhand der folgenden Referenz verglichen:Aber alle Ihre Artikel haben einen unterschiedlichen Wert von
ID
. Also alle Gegenstände immer noch als unterschiedlich angesehen. Wenn Sie mehrere Artikel mit demselben versehen, sehenID
Sie einen Unterschied zwischenUnion
undConcat
:Ihr erstes Beispiel funktioniert, da Ganzzahlen Werttypen sind und nach Wert verglichen werden.
quelle
x.Union(y)
ist das gleiche wiex.Concat(y).Distinct()
. Der Unterschied besteht also nur in der BewerbungDistinct
. Wie wählt Linq unterschiedliche (dh unterschiedliche) Objekte in verketteten Sequenzen aus? In Ihrem Beispielcode (aus Frage) vergleicht Linq Objekte anhand der Referenz (dh der Adresse im Speicher). Wenn Sie ein neues Objekt über dennew
Operator erstellen , weist es Speicher an einer neuen Adresse zu. Wenn Sie also vier neu erstellte Objekte haben, sind die Adressen unterschiedlich. Und alle Objekte werden unterschiedlich sein. SomitDistinct
werden alle Objekte aus der Sequenz zurückgegeben.Concat
Gibt buchstäblich die Elemente aus der ersten Sequenz zurück, gefolgt von den Elementen aus der zweiten Sequenz. Wenn SieConcat
zwei Sequenzen mit 2 Elementen verwenden, erhalten Sie immer eine Sequenz mit 4 Elementen.Union
wird im WesentlichenConcat
gefolgt vonDistinct
.In Ihren ersten beiden Fällen erhalten Sie Sequenzen mit zwei Elementen, da zwischen ihnen jedes Paar von Eingabequadraten genau zwei unterschiedliche Elemente enthält.
In Ihrem dritten Fall erhalten Sie eine Sequenz mit 4 Elementen, da alle vier Elemente in Ihren beiden Eingabesequenzen unterschiedlich sind .
quelle
Union
undConcat
verhalten sich gleich, daUnion
Duplikate ohne Custom nicht erkannt werden könnenIEqualityComparer<X>
. Es wird nur gesucht, ob beide dieselbe Referenz sind.Jetzt können Sie es in der Überladung von verwenden
Union
:quelle