Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die System.Collections Klassen führen Vergleiche in fast allen Prozessen durch, die an der Verwaltung von Sammlungen beteiligt sind, unabhängig davon, ob das Element zum Entfernen oder Zurückgeben des Werts eines Schlüssel- und Wertpaars gesucht wird.
Sammlungen verwenden in der Regel einen Gleichheitsvergleich und/oder einen Sortiervergleich. Für Vergleiche werden zwei Konstrukte verwendet.
Gleichheit prüfen
Methoden wie Contains
, IndexOf, LastIndexOfund Remove
verwenden einen Gleichheitsvergleich für die Auflistungselemente. Wenn die Sammlung generisch ist, werden Elemente gemäß den folgenden Richtlinien für die Gleichheit verglichen:
Wenn typ T die IEquatable<T> generische Schnittstelle implementiert, ist der Gleichheitsvergleich die Equals Methode dieser Schnittstelle.
Wenn Typ T IEquatable<T> nicht implementiert wird, wird Object.Equals verwendet.
Darüber hinaus akzeptieren einige Konstruktorüberladungen für Wörterbuchauflistungen eine IEqualityComparer<T> -Implementierung, die zum Vergleichen von Schlüsseln auf Gleichheit verwendet wird. Ein Beispiel finden Sie im Dictionary<TKey,TValue> Konstruktor.
Bestimmen der Sortierreihenfolge
Methoden wie BinarySearch
z. B. und Sort
verwenden einen Sortiervergleich für die Sammlungselemente. Die Vergleiche können zwischen Elementen der Auflistung oder zwischen einem Element und einem angegebenen Wert sein. Zum Vergleichen von Objekten gibt es das Konzept eines default comparer
und eines explicit comparer
.
Der Standardvergleich basiert auf mindestens einem der Objekte, die verglichen werden, um die IComparable-Schnittstelle zu implementieren. Es empfiehlt sich, IComparable für alle Klassen zu implementieren, die als Werte in einer Listensammlung oder als Schlüssel in einer Wörterbuchsammlung verwendet werden. Bei einer generischen Sammlung wird der Gleichheitsvergleich gemäß den folgenden Angaben bestimmt:
Wenn typ T die System.IComparable<T> generische Schnittstelle implementiert, ist der Standard-Comparer die IComparable<T>.CompareTo(T) Methode dieser Schnittstelle.
Wenn typ T die nicht generische System.IComparable Schnittstelle implementiert, ist der Standardvergleich die IComparable.CompareTo(Object) Methode dieser Schnittstelle.
Wenn Typ T keine der Schnittstellen implementiert, gibt es keinen Standardvergleich, und ein Vergleich oder ein Vergleichsdelegat muss explizit angegeben werden.
Um explizite Vergleiche bereitzustellen, akzeptieren einige Methoden eine IComparer-Implementierung als Parameter. Die Methode List<T>.Sort akzeptiert beispielsweise eine System.Collections.Generic.IComparer<T> Implementierung.
Die aktuelle Kultureinstellung des Systems kann sich auf die Vergleiche und Sortierungen innerhalb einer Sammlung auswirken. Standardmäßig sind die Vergleiche und Sortierungen in den Auflistungsklassen kulturempfindlich. Um die Kultureinstellung zu ignorieren und daher konsistente Vergleichs- und Sortierergebnisse zu erhalten, verwenden Sie InvariantCulture mit Memberüberladungen, die CultureInfoakzeptieren. Weitere Informationen finden Sie unter Ausführen von Kultur-insensitive Zeichenfolgenvorgänge in Auflistungen und Ausführen von Kultur-insensitive Zeichenfolgenvorgänge in Arrays.
Beispiel für Gleichheit und Sortierung
Der folgende Code veranschaulicht eine Implementierung von IEquatable<T> und IComparable<T> für ein einfaches Geschäftsobjekt. Darüber hinaus werden Sie feststellen, dass das Aufrufen der Methode Sort() zur Verwendung des Standardvergleichers für den Typ Part
führt, und die Methode Sort(Comparison<T>) wird durch eine anonyme Methode implementiert, wenn das Objekt in einer Liste gespeichert und sortiert wird.
using System;
using System.Collections.Generic;
// Simple business object. A PartId is used to identify the
// type of part but the part name can change.
public class Part : IEquatable<Part>, IComparable<Part>
{
public string PartName { get; set; }
public int PartId { get; set; }
public override string ToString() =>
$"ID: {PartId} Name: {PartName}";
public override bool Equals(object obj) =>
(obj is Part part)
? Equals(part)
: false;
public int SortByNameAscending(string name1, string name2) =>
name1?.CompareTo(name2) ?? 1;
// Default comparer for Part type.
// A null value means that this object is greater.
public int CompareTo(Part comparePart) =>
comparePart == null ? 1 : PartId.CompareTo(comparePart.PartId);
public override int GetHashCode() => PartId;
public bool Equals(Part other) =>
other is null ? false : PartId.Equals(other.PartId);
// Should also override == and != operators.
}
public class Example
{
public static void Main()
{
// Create a list of parts.
var parts = new List<Part>
{
// Add parts to the list.
new Part { PartName = "regular seat", PartId = 1434 },
new Part { PartName = "crank arm", PartId = 1234 },
new Part { PartName = "shift lever", PartId = 1634 },
// Name intentionally left null.
new Part { PartId = 1334 },
new Part { PartName = "banana seat", PartId = 1444 },
new Part { PartName = "cassette", PartId = 1534 }
};
// Write out the parts in the list. This will call the overridden
// ToString method in the Part class.
Console.WriteLine("\nBefore sort:");
parts.ForEach(Console.WriteLine);
// Call Sort on the list. This will use the
// default comparer, which is the Compare method
// implemented on Part.
parts.Sort();
Console.WriteLine("\nAfter sort by part number:");
parts.ForEach(Console.WriteLine);
// This shows calling the Sort(Comparison<T> comparison) overload using
// a lambda expression as the Comparison<T> delegate.
// This method treats null as the lesser of two values.
parts.Sort((Part x, Part y) =>
x.PartName == null && y.PartName == null
? 0
: x.PartName == null
? -1
: y.PartName == null
? 1
: x.PartName.CompareTo(y.PartName));
Console.WriteLine("\nAfter sort by name:");
parts.ForEach(Console.WriteLine);
/*
Before sort:
ID: 1434 Name: regular seat
ID: 1234 Name: crank arm
ID: 1634 Name: shift lever
ID: 1334 Name:
ID: 1444 Name: banana seat
ID: 1534 Name: cassette
After sort by part number:
ID: 1234 Name: crank arm
ID: 1334 Name:
ID: 1434 Name: regular seat
ID: 1444 Name: banana seat
ID: 1534 Name: cassette
ID: 1634 Name: shift lever
After sort by name:
ID: 1334 Name:
ID: 1444 Name: banana seat
ID: 1534 Name: cassette
ID: 1234 Name: crank arm
ID: 1434 Name: regular seat
ID: 1634 Name: shift lever
*/
}
}
Imports System.Collections.Generic
' Simple business object. A PartId is used to identify the type of part
' but the part name can change.
Public Class Part
Implements IEquatable(Of Part)
Implements IComparable(Of Part)
Public Property PartName() As String
Get
Return m_PartName
End Get
Set(value As String)
m_PartName = Value
End Set
End Property
Private m_PartName As String
Public Property PartId() As Integer
Get
Return m_PartId
End Get
Set(value As Integer)
m_PartId = Value
End Set
End Property
Private m_PartId As Integer
Public Overrides Function ToString() As String
Return "ID: " & PartId & " Name: " & PartName
End Function
Public Overrides Function Equals(obj As Object) As Boolean
If obj Is Nothing Then
Return False
End If
Dim objAsPart As Part = TryCast(obj, Part)
If objAsPart Is Nothing Then
Return False
Else
Return Equals(objAsPart)
End If
End Function
Public Function SortByNameAscending(name1 As String, name2 As String) As Integer
Return name1.CompareTo(name2)
End Function
' Default comparer for Part.
Public Function CompareTo(comparePart As Part) As Integer _
Implements IComparable(Of ListSortVB.Part).CompareTo
' A null value means that this object is greater.
If comparePart Is Nothing Then
Return 1
Else
Return Me.PartId.CompareTo(comparePart.PartId)
End If
End Function
Public Overrides Function GetHashCode() As Integer
Return PartId
End Function
Public Overloads Function Equals(other As Part) As Boolean Implements IEquatable(Of ListSortVB.Part).Equals
If other Is Nothing Then
Return False
End If
Return (Me.PartId.Equals(other.PartId))
End Function
' Should also override == and != operators.
End Class
Public Class Example
Public Shared Sub Main()
' Create a list of parts.
Dim parts As New List(Of Part)()
' Add parts to the list.
parts.Add(New Part() With { _
.PartName = "regular seat", _
.PartId = 1434 _
})
parts.Add(New Part() With { _
.PartName = "crank arm", _
.PartId = 1234 _
})
parts.Add(New Part() With { _
.PartName = "shift lever", _
.PartId = 1634 _
})
' Name intentionally left null.
parts.Add(New Part() With { _
.PartId = 1334 _
})
parts.Add(New Part() With { _
.PartName = "banana seat", _
.PartId = 1444 _
})
parts.Add(New Part() With { _
.PartName = "cassette", _
.PartId = 1534 _
})
' Write out the parts in the list. This will call the overridden
' ToString method in the Part class.
Console.WriteLine(vbLf & "Before sort:")
For Each aPart As Part In parts
Console.WriteLine(aPart)
Next
' Call Sort on the list. This will use the
' default comparer, which is the Compare method
' implemented on Part.
parts.Sort()
Console.WriteLine(vbLf & "After sort by part number:")
For Each aPart As Part In parts
Console.WriteLine(aPart)
Next
' This shows calling the Sort(Comparison(T) overload using
' an anonymous delegate method.
' This method treats null as the lesser of two values.
parts.Sort(Function(x As Part, y As Part)
If x.PartName Is Nothing AndAlso y.PartName Is Nothing Then
Return 0
ElseIf x.PartName Is Nothing Then
Return -1
ElseIf y.PartName Is Nothing Then
Return 1
Else
Return x.PartName.CompareTo(y.PartName)
End If
End Function)
Console.WriteLine(vbLf & "After sort by name:")
For Each aPart As Part In parts
Console.WriteLine(aPart)
Next
'
'
' Before sort:
' ID: 1434 Name: regular seat
' ID: 1234 Name: crank arm
' ID: 1634 Name: shift lever
' ID: 1334 Name:
' ID: 1444 Name: banana seat
' ID: 1534 Name: cassette
'
' After sort by part number:
' ID: 1234 Name: crank arm
' ID: 1334 Name:
' ID: 1434 Name: regular seat
' ID: 1444 Name: banana seat
' ID: 1534 Name: cassette
' ID: 1634 Name: shift lever
'
' After sort by name:
' ID: 1334 Name:
' ID: 1444 Name: banana seat
' ID: 1534 Name: cassette
' ID: 1234 Name: crank arm
' ID: 1434 Name: regular seat
' ID: 1634 Name: shift lever
End Sub
End Class