Поделиться через


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;
        }
    }
}
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> интерфейса для использования с классами коллекций, такими как универсальные SortedList<TKey,TValue> классы и SortedDictionary<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)

Сравнение двух объектов и возврат значения, указывающего, является ли один объект меньшим, равным или большим другого.

Применяется к

См. также раздел