Нужна помощь в понимании того, как List <T>.Sort (IComparer (T)) знает значение для сортировки - PullRequest
3 голосов
/ 29 июля 2010

Я работаю над программой (изучаю C #), которая создает объект (Card) и в программе сортирует колоду карт по значению.Меня сбивает с толку то, как можно сортировать колоду карт по значению карт, когда экземпляр объекта - это не параметр, передаваемый методу, а объект класса.Ниже приведен код, помогающий ответить на мой вопрос - я бы выполнил следующее, если бы передавал экземплярный объект.

Класс для создания объекта:

class Card
{
    public Suits Suit { get; set; }
    public Values Value { get; set; }

    public Card(Suits suit, Values value)
    {
        this.Suit = suit;
        this.Value = value;
    }

    public string Name
    {
        get { return Value.ToString() + " of " + Suit.ToString(); }
    }

    public override string ToString()
    {
        return Name;
    }
}

В другом классе я нахожусьвызов метода, который создает экземпляр объекта (CardComparer_byValue), который наследуется от интерфейса IComparer.Вот тут-то и возникает моя путаница.

public void SortByValue() {
cards.Sort(new CardComparer_byValue());
} 

И класс SortByValue

class CardComparer_byValue : IComparer<Card>
{
    public int Compare(Card x, Card y)
    {
        if (x.Value > y.Value)
            return 1;
        if (x.Value < y.Value)
            return -1;
        if (x.Suit > y.Suit)
            return 1;
        if (x.Suit < y.Suit)
            return -1;
        return 0;
    }

} 

Я думаю, что вышеуказанный метод "SortByValue" был назван так

Card mycard = new Card("Spades", 4);
public void SortByValue() {
cards.Sort(new CardComparer_byValue(mycard));
} 

Так кто-нибудь объяснит мне, что мне не хватает, как сортировка может работать таким образом?

Ответы [ 3 ]

5 голосов
/ 29 июля 2010

Сортирует всю коллекцию, а не по определенной «карточке».

Вот почему метод Compare определяется следующим образом:

public int Compare(Card x, Card y)

Он использует «Карту х» и«Карта y», вызывающая это для пар элементов в коллекции cards, чтобы отсортировать ее.Метод Sort вызывает этот метод Compare много раз , используя его для сортировки всей коллекции путем сравнения элементов в парах по одной паре за раз.

1 голос
/ 29 июля 2010

Класс, реализующий IComparer<T>, должен иметь метод Compare(T x, T y), который Sort вызывает неоднократно во время операций сортировки.

Поскольку Сортировка находится на List<T> у вас есть более одной карты, с которой вы имеете дело.List<T> использует метод Array.Sort , который использует алгоритм QuickSort для их сортировки.

0 голосов
/ 29 июля 2010
new CardComparer_byValue(mycard));

Здесь вы не вызываете метод - вы пытаетесь создать объект. Класс не определяет конструктор, который принимает объект Card, поэтому вы получите ошибку синтаксиса при компиляции.

Здесь важно отметить, что объект IComparer - это просто объект . Это как маленький судья, чтобы определить порядок. («Я бы хотел, чтобы вы переупорядочили мои карточки, а вот мистер Бернштейн расскажет вам, в каком порядке они будут».)

Итак, где-то глубоко внутри метода Sort есть строка вроде:

  if (cmp.Compare(lhsCard, rhsCard) > 0)
       /* swap lhsCard & rhsCard */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...