Comparer<T> Класс
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Предоставляет базовый класс для реализации универсального IComparer<T> интерфейса.
generic <typename T>
public ref class Comparer abstract : System::Collections::Generic::IComparer<T>, System::Collections::IComparer
public abstract class Comparer<T> : System.Collections.Generic.IComparer<T>, System.Collections.IComparer
[System.Serializable]
public abstract class Comparer<T> : System.Collections.Generic.IComparer<T>, System.Collections.IComparer
type Comparer<'T> = class
interface IComparer<'T>
interface IComparer
[<System.Serializable>]
type Comparer<'T> = class
interface IComparer
interface IComparer<'T>
Public MustInherit Class Comparer(Of T)
Implements IComparer, IComparer(Of T)
Параметры типа
- T
Тип объектов для сравнения.
- Наследование
-
Comparer<T>
- Атрибуты
- Реализации
Примеры
В следующем примере класс является производным BoxLengthFirstот Comparer<T> класса. Этот средство сравнения сравнивает два объекта типа Box. Он сортирует их сначала по длине, а затем по высоте, а затем по ширине. Класс Box реализует IComparable<T> интерфейс для управления сравнением по умолчанию между двумя Box объектами. Эта реализация по умолчанию сначала сортируется по высоте, а затем по длине, а затем по ширине. В примере показаны различия между двумя сравнениями путем сортировки списка Box объектов сначала с помощью BoxLengthFirst средства сравнения, а затем с помощью средства сравнения по умолчанию.
using System;
using System.Collections;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
List<Box> Boxes = new List<Box>();
Boxes.Add(new Box(4, 20, 14));
Boxes.Add(new Box(12, 12, 12));
Boxes.Add(new Box(8, 20, 10));
Boxes.Add(new Box(6, 10, 2));
Boxes.Add(new Box(2, 8, 4));
Boxes.Add(new Box(2, 6, 8));
Boxes.Add(new Box(4, 12, 20));
Boxes.Add(new Box(18, 10, 4));
Boxes.Add(new Box(24, 4, 18));
Boxes.Add(new Box(10, 4, 16));
Boxes.Add(new Box(10, 2, 10));
Boxes.Add(new Box(6, 18, 2));
Boxes.Add(new Box(8, 12, 4));
Boxes.Add(new Box(12, 10, 8));
Boxes.Add(new Box(14, 6, 6));
Boxes.Add(new Box(16, 6, 16));
Boxes.Add(new Box(2, 8, 12));
Boxes.Add(new Box(4, 24, 8));
Boxes.Add(new Box(8, 6, 20));
Boxes.Add(new Box(18, 18, 12));
// Sort by an Comparer<T> implementation that sorts
// first by the length.
Boxes.Sort(new BoxLengthFirst());
Console.WriteLine("H - L - W");
Console.WriteLine("==========");
foreach (Box bx in Boxes)
{
Console.WriteLine("{0}\t{1}\t{2}",
bx.Height.ToString(), bx.Length.ToString(),
bx.Width.ToString());
}
Console.WriteLine();
Console.WriteLine("H - L - W");
Console.WriteLine("==========");
// Get the default comparer that
// sorts first by the height.
Comparer<Box> defComp = Comparer<Box>.Default;
// Calling Boxes.Sort() with no parameter
// is the same as calling Boxs.Sort(defComp)
// because they are both using the default comparer.
Boxes.Sort();
foreach (Box bx in Boxes)
{
Console.WriteLine("{0}\t{1}\t{2}",
bx.Height.ToString(), bx.Length.ToString(),
bx.Width.ToString());
}
// This explicit interface implementation
// compares first by the length.
// Returns -1 because the length of BoxA
// is less than the length of BoxB.
BoxLengthFirst LengthFirst = new BoxLengthFirst();
Comparer<Box> bc = (Comparer<Box>) LengthFirst;
Box BoxA = new Box(2, 6, 8);
Box BoxB = new Box(10, 12, 14);
int x = LengthFirst.Compare(BoxA, BoxB);
Console.WriteLine();
Console.WriteLine(x.ToString());
}
}
public class BoxLengthFirst : Comparer<Box>
{
// Compares by Length, Height, and Width.
public override int Compare(Box x, Box y)
{
if (x.Length.CompareTo(y.Length) != 0)
{
return x.Length.CompareTo(y.Length);
}
else if (x.Height.CompareTo(y.Height) != 0)
{
return x.Height.CompareTo(y.Height);
}
else if (x.Width.CompareTo(y.Width) != 0)
{
return x.Width.CompareTo(y.Width);
}
else
{
return 0;
}
}
}
// This class is not demonstrated in the Main method
// and is provided only to show how to implement
// the interface. It is recommended to derive
// from Comparer<T> instead of implementing IComparer<T>.
public class BoxComp : IComparer<Box>
{
// Compares by Height, Length, and Width.
public int Compare(Box x, Box y)
{
if (x.Height.CompareTo(y.Height) != 0)
{
return x.Height.CompareTo(y.Height);
}
else if (x.Length.CompareTo(y.Length) != 0)
{
return x.Length.CompareTo(y.Length);
}
else if (x.Width.CompareTo(y.Width) != 0)
{
return x.Width.CompareTo(y.Width);
}
else
{
return 0;
}
}
}
public class Box : IComparable<Box>
{
public Box(int h, int l, int w)
{
this.Height = h;
this.Length = l;
this.Width = w;
}
public int Height { get; private set; }
public int Length { get; private set; }
public int Width { get; private set; }
public int CompareTo(Box other)
{
// Compares Height, Length, and Width.
if (this.Height.CompareTo(other.Height) != 0)
{
return this.Height.CompareTo(other.Height);
}
else if (this.Length.CompareTo(other.Length) != 0)
{
return this.Length.CompareTo(other.Length);
}
else if (this.Width.CompareTo(other.Width) != 0)
{
return this.Width.CompareTo(other.Width);
}
else
{
return 0;
}
}
}
open System
open System.Collections.Generic
type Box(h, l, w) =
member val Height: int = h with get
member val Length: int = l with get
member val Width: int = w with get
interface IComparable<Box> with
member this.CompareTo(other) =
// Compares Height, Length, and Width.
if this.Height.CompareTo other.Height <> 0 then
this.Height.CompareTo other.Height
elif this.Length.CompareTo other.Length <> 0 then
this.Length.CompareTo other.Length
elif this.Width.CompareTo other.Width <> 0 then
this.Width.CompareTo other.Width
else
0
type BoxLengthFirst() =
inherit Comparer<Box>()
// Compares by Length, Height, and Width.
override _.Compare(x: Box, y: Box) =
if x.Length.CompareTo y.Length <> 0 then
x.Length.CompareTo y.Length
elif x.Height.CompareTo y.Height <> 0 then
x.Height.CompareTo y.Height
elif x.Width.CompareTo y.Width <> 0 then
x.Width.CompareTo y.Width
else
0
let boxes = ResizeArray<Box>()
boxes.Add(Box(4, 20, 14))
boxes.Add(Box(12, 12, 12))
boxes.Add(Box(8, 20, 10))
boxes.Add(Box(6, 10, 2))
boxes.Add(Box(2, 8, 4))
boxes.Add(Box(2, 6, 8))
boxes.Add(Box(4, 12, 20))
boxes.Add(Box(18, 10, 4))
boxes.Add(Box(24, 4, 18))
boxes.Add(Box(10, 4, 16))
boxes.Add(Box(10, 2, 10))
boxes.Add(Box(6, 18, 2))
boxes.Add(Box(8, 12, 4))
boxes.Add(Box(12, 10, 8))
boxes.Add(Box(14, 6, 6))
boxes.Add(Box(16, 6, 16))
boxes.Add(Box(2, 8, 12))
boxes.Add(Box(4, 24, 8))
boxes.Add(Box(8, 6, 20))
boxes.Add(Box(18, 18, 12))
// Sort by an Comparer<T> implementation that sorts
// first by the length.
boxes.Sort(BoxLengthFirst())
printfn "H - L - W"
printfn "=========="
for bx in boxes do
printfn $"{bx.Height}\t{bx.Length}\t{bx.Width}"
printfn ""
printfn "H - L - W"
printfn "=========="
// Get the default comparer that
// sorts first by the height.
let defComp = Comparer<Box>.Default
// Calling Boxes.Sort() with no parameter
// is the same as calling boxes.Sort defComp
// because they are both using the default comparer.
boxes.Sort()
for bx in boxes do
printfn $"{bx.Height}\t{bx.Length}\t{bx.Width}"
// This explicit interface implementation
// compares first by the length.
// Returns -1 because the length of BoxA
// is less than the length of BoxB.
let LengthFirst = BoxLengthFirst()
let bc = LengthFirst :> Comparer<Box>
let BoxA = Box(2, 6, 8)
let BoxB = Box(10, 12, 14)
let x = LengthFirst.Compare(BoxA, BoxB)
printfn $"\n{x}"
// This class is not demonstrated in the Main method
// and is provided only to show how to implement
// the interface. It is recommended to derive
// from Comparer<T> instead of implementing IComparer<T>.
type BoxComp() =
interface IComparer<Box> with
// Compares by Height, Length, and Width.
member _.Compare(x: Box, y: Box) =
if x.Height.CompareTo(y.Height) <> 0 then
x.Height.CompareTo(y.Height)
elif x.Length.CompareTo(y.Length) <> 0 then
x.Length.CompareTo(y.Length)
elif x.Width.CompareTo(y.Width) <> 0 then
x.Width.CompareTo(y.Width)
else
0
Imports System.Collections.Generic
Friend Class Program
Shared Sub Main(ByVal args() As String)
Dim Boxes As New List(Of Box)()
Boxes.Add(New Box(4, 20, 14))
Boxes.Add(New Box(12, 12, 12))
Boxes.Add(New Box(8, 20, 10))
Boxes.Add(New Box(6, 10, 2))
Boxes.Add(New Box(2, 8, 4))
Boxes.Add(New Box(2, 6, 8))
Boxes.Add(New Box(4, 12, 20))
Boxes.Add(New Box(18, 10, 4))
Boxes.Add(New Box(24, 4, 18))
Boxes.Add(New Box(10, 4, 16))
Boxes.Add(New Box(10, 2, 10))
Boxes.Add(New Box(6, 18, 2))
Boxes.Add(New Box(8, 12, 4))
Boxes.Add(New Box(12, 10, 8))
Boxes.Add(New Box(14, 6, 6))
Boxes.Add(New Box(16, 6, 16))
Boxes.Add(New Box(2, 8, 12))
Boxes.Add(New Box(4, 24, 8))
Boxes.Add(New Box(8, 6, 20))
Boxes.Add(New Box(18, 18, 12))
' Sort by an Comparer<T> implementation that sorts
' first by the length.
Boxes.Sort(New BoxLengthFirst())
Console.WriteLine("H - L - W")
Console.WriteLine("==========")
For Each bx As Box In Boxes
Console.WriteLine("{0}" & vbTab & "{1}" & vbTab & "{2}", _
bx.Height.ToString(), bx.Length.ToString(), _
bx.Width.ToString())
Next bx
Console.WriteLine()
Console.WriteLine("H - L - W")
Console.WriteLine("==========")
' Get the default comparer that
' sorts first by the height.
Dim defComp As Comparer(Of Box) = Comparer(Of Box).Default
' Calling Boxes.Sort() with no parameter
' is the same as calling Boxs.Sort(defComp)
' because they are both using the default comparer.
Boxes.Sort()
For Each bx As Box In Boxes
Console.WriteLine("{0}" & vbTab & "{1}" & vbTab & "{2}", _
bx.Height.ToString(), _
bx.Length.ToString(), _
bx.Width.ToString())
Next bx
' This explicit interface implementation
' compares first by the length.
' Returns -1 because the length of BoxA
' is less than the length of BoxB.
Dim LengthFirst As New BoxLengthFirst()
Dim bc As Comparer(Of Box) = CType(LengthFirst, Comparer(Of Box))
Dim BoxA As New Box(2, 6, 8)
Dim BoxB As New Box(10, 12, 14)
Dim x As Integer = LengthFirst.Compare(BoxA, BoxB)
Console.WriteLine()
Console.WriteLine(x.ToString())
End Sub
End Class
Public Class BoxLengthFirst
Inherits Comparer(Of Box)
' Compares by Length, Height, and Width.
Public Overrides Function Compare(ByVal x As Box, ByVal y As Box) As Integer
If x.Length.CompareTo(y.Length) <> 0 Then
Return x.Length.CompareTo(y.Length)
ElseIf x.Height.CompareTo(y.Height) <> 0 Then
Return x.Height.CompareTo(y.Height)
ElseIf x.Width.CompareTo(y.Width) <> 0 Then
Return x.Width.CompareTo(y.Width)
Else
Return 0
End If
End Function
End Class
' This class is not demonstrated in the Main method
' and is provided only to show how to implement
' the interface. It is recommended to derive
' from Comparer<T> instead of implementing IComparer<T>.
Public Class BoxComp
Implements IComparer(Of Box)
' Compares by Height, Length, and Width.
Public Function Compare(ByVal x As Box, ByVal y As Box) As Integer Implements _
IComparer(Of Box).Compare
If x.Height.CompareTo(y.Height) <> 0 Then
Return x.Height.CompareTo(y.Height)
ElseIf x.Length.CompareTo(y.Length) <> 0 Then
Return x.Length.CompareTo(y.Length)
ElseIf x.Width.CompareTo(y.Width) <> 0 Then
Return x.Width.CompareTo(y.Width)
Else
Return 0
End If
End Function
End Class
Public Class Box
Implements IComparable(Of Box)
Public Sub New(ByVal h As Integer, ByVal l As Integer, ByVal w As Integer)
Me.Height = h
Me.Length = l
Me.Width = w
End Sub
Private privateHeight As Integer
Public Property Height() As Integer
Get
Return privateHeight
End Get
Private Set(ByVal value As Integer)
privateHeight = value
End Set
End Property
Private privateLength As Integer
Public Property Length() As Integer
Get
Return privateLength
End Get
Private Set(ByVal value As Integer)
privateLength = value
End Set
End Property
Private privateWidth As Integer
Public Property Width() As Integer
Get
Return privateWidth
End Get
Private Set(ByVal value As Integer)
privateWidth = value
End Set
End Property
Public Function CompareTo(ByVal other As Box) As Integer _
Implements IComparable(Of Box).CompareTo
' Compares Height, Length, and Width.
If Me.Height.CompareTo(other.Height) <> 0 Then
Return Me.Height.CompareTo(other.Height)
ElseIf Me.Length.CompareTo(other.Length) <> 0 Then
Return Me.Length.CompareTo(other.Length)
ElseIf Me.Width.CompareTo(other.Width) <> 0 Then
Return Me.Width.CompareTo(other.Width)
Else
Return 0
End If
End Function
End Class
Комментарии
Производный от этого класса для предоставления пользовательской IComparer<T> реализации интерфейса для использования с классами коллекции, такими как и SortedDictionary<TKey,TValue> универсальные SortedList<TKey,TValue> классы.
Разница между производным от Comparer<T> класса и реализацией System.IComparable интерфейса выглядит следующим образом:
Чтобы указать, как по умолчанию следует сравнить два объекта, реализуйте System.IComparable интерфейс в классе. Это гарантирует, что операции сортировки будут использовать предоставленный вами код сравнения по умолчанию.
Чтобы определить средство сравнения, используемое вместо средства сравнения по умолчанию, наследуйте от Comparer<T> класса. Затем этот средство сравнения можно использовать в операциях сортировки, которые принимают сравнение в качестве параметра.
Объект, возвращаемый Default свойством, использует универсальный System.IComparable<T> интерфейс (IComparable<T> в C#, IComparable(Of T) в Visual Basic) для сравнения двух объектов. Если тип T не реализует универсальный System.IComparable<T> интерфейс, Default свойство возвращает Comparer<T> свойство, использующее System.IComparable интерфейс.
Примечания для тех, кто реализует этот метод
Compare(T, T) и Equals(T, T) может вести себя по-разному с точки зрения конфиденциальности языка и регистра.
Для сравнения StringComparer строк рекомендуется использовать Comparer<String>класс.
StringComparer Свойства класса возвращают предопределенные экземпляры, которые выполняют сравнение строк с различными сочетаниями конфиденциальности языка и регистра. Конфиденциальность регистра и конфиденциальность языка и региональных параметров согласованы между членами одного StringComparer экземпляра.
Дополнительные сведения о сравнениях, относящихся к языку и региональным параметрам, см. в System.Globalization пространстве имен и глобализации и локализации.
Конструкторы
| Имя | Описание |
|---|---|
| Comparer<T>() |
Инициализирует новый экземпляр класса Comparer<T>. |
Свойства
| Имя | Описание |
|---|---|
| Default |
Возвращает средство сравнения сортировки по умолчанию для типа, указанного универсальным аргументом. |
Методы
| Имя | Описание |
|---|---|
| Compare(T, T) |
При переопределении в производном классе выполняет сравнение двух объектов одного типа и возвращает значение, указывающее, меньше ли один объект, равен или больше другого. |
| Create(Comparison<T>) |
Создает средство сравнения с помощью указанного сравнения. |
| Equals(Object) |
Определяет, равен ли указанный объект текущему объекту. (Унаследовано от Object) |
| GetHashCode() |
Служит хэш-функцией по умолчанию. (Унаследовано от Object) |
| GetType() |
Возвращает Type текущего экземпляра. (Унаследовано от Object) |
| MemberwiseClone() |
Создает неглубокую копию текущей Object. (Унаследовано от Object) |
| ToString() |
Возвращает строку, представляющую текущий объект. (Унаследовано от Object) |
Явные реализации интерфейса
| Имя | Описание |
|---|---|
| IComparer.Compare(Object, Object) |
Сравнивает два объекта и возвращает значение, указывающее, меньше ли одно, равно или больше другого. |