Оператор List‹T› == В спецификации языка C#, версия 4

В Спецификации языка C# версии 4, 1.6.7.5 Операторы — это информация об List<T> операторах: == и !=. Но я не могу найти такие операторы, определенные в List<T>? Я что-то пропустил?

Пример кода из 1.6.7.5 Операторы:

List<int> a = new List<int>();
a.Add(1);
a.Add(2);
List<int> b = new List<int>();
b.Add(1);
b.Add(2);
Console.WriteLine(a == b); // Outputs "True" => here I get False as well
b.Add(3);
Console.WriteLine(a == b); // Outputs "False"

person Daniel Dušek    schedule 07.08.2012    source источник
comment
Пожалуйста, объясните ваш вопрос яснее   -  person darnir    schedule 07.08.2012
comment
Пожалуйста, не говорите «Выводы», потому что я бы хотел, чтобы это было .. :)   -  person    schedule 07.08.2012
comment
@pst Этот код дословно копируется и вставляется из спецификации языка вместе с комментарием.   -  person Sergey Kalinichenko    schedule 07.08.2012


Ответы (2)


Спецификация действительно правильная, хотя и запутанная. Спецификация определяет класс под названием List (плохой выбор имени).

В следующей таблице показан универсальный класс List, который реализует расширяемый список объектов. Класс содержит несколько примеров наиболее распространенных видов функций-членов.

Этот класс можно увидеть в спецификации в разделе 1.6.7. Оператор Equals перегружен и соответствует выходным данным, описанным выше. Возможно, для этого класса следовало бы выбрать лучшее имя.

static bool Equals(List<T> a, List<T> b) {
    if (a == null) return b == null;
    if (b == null || a.count != b.count) return false;
    for (int i = 0; i < a.count; i++) {
        if (!object.Equals(a.items[i], b.items[i])) {
            return false;
        }
    }
  return true;
}
person Dylan Meador    schedule 07.08.2012

List<T> — это ссылочный тип, который не перегружает operator==. Поэтому он использует семантику равенства ссылок по умолчанию. Кажется, у вас сложилось впечатление, что он переопределяет operator== для обеспечения семантики значений, но это не так. a будет равно b, когда a и b оба ссылаются на один и тот же экземпляр List<T>.

РЕДАКТИРОВАТЬ: Итак, я сам посмотрел на спецификацию. В нем говорится:

Класс List объявляет два оператора: оператор == и оператор !=, что придает новый смысл выражениям, применяющим эти операторы к экземплярам List. В частности, операторы определяют равенство двух экземпляров List как сравнение каждого из содержащихся объектов с использованием их методов Equals. В следующем примере используется оператор == для сравнения двух экземпляров List.

Честно... Я понятия не имею, о чем они говорят, но это не похоже на правду. Насколько я могу судить после запуска нескольких тестов, класс List<T> использует ссылочное равенство. Хороший вопрос.

EDIT2: декомпилировано List<T>, без перегрузки operator== и/или operator!=. Спецификация в данном случае выглядит совершенно неправильно.

person Ed S.    schedule 07.08.2012
comment
Спецификация языка говорит об обратном: класс List‹T› объявляет два оператора, оператор == и оператор !=, и, таким образом, придает новый смысл выражениям, применяющим эти операторы к экземплярам List. В частности, операторы определяют равенство двух экземпляров List‹T› как сравнение каждого из содержащихся объектов с использованием их методов Equals. - person Sergey Kalinichenko; 07.08.2012
comment
@dasblinkenlight: Вы правы, сейчас читаю. Пытаюсь разобраться... - person Ed S.; 07.08.2012
comment
@DanielDusek: Да, я только что добавил это в свой пост. Это кажется неправильным. Реальность не соответствует спецификации. - person Ed S.; 07.08.2012
comment
@JamesMichaelHare: То же самое (пришлось покопаться в рабочей версии рефлектора...). Похоже, что спецификация просто неверна в этом вопросе. - person Ed S.; 07.08.2012
comment
Да, я думал, что спецификация пыталась проиллюстрировать и выбрала плохой пример. Этот пункт спецификации, однако, не означает, что List<T> должен поддерживать эти операторы, это был просто неправильный пример того, который предположительно поддерживает... - person James Michael Hare; 07.08.2012
comment
@JamesMichaelHare: Согласен, очень плохо, что они выбрали тип для примера, который сделал его совершенно неверным. Даже один и тот же код неправильный! - person Ed S.; 07.08.2012
comment
@JamesMichaelHare, вы правы. Посмотрите на место, где вы все читаете. В любом случае, спецификации — это не место для изучения List‹T› — для этого существует MSDN. Спецификации относятся к строительным блокам языка C#. Список‹T› не является одним из его строительных блоков :) - person Jony Adamit; 07.08.2012
comment
@JonyAdamnit...: Ну, хорошо, но я не думаю, что это оправдание того, что спецификация явно неверна. - person Ed S.; 07.08.2012
comment
@JonyAdamnit... Верно, очень верно. Тем не менее, неудачный пример. - person James Michael Hare; 07.08.2012
comment
@ЭдС. Я думаю, что меня больше удивляет то, что List<T> существует со времен .NET 2.0, странно, что они не нашли этого (или, по крайней мере, не исправили). - person James Michael Hare; 07.08.2012
comment
Если вы посмотрите на спецификацию C# 1.2, вы увидите нечто очень похожее. List‹T› не существовало на момент его написания. - person Jony Adamit; 07.08.2012
comment
@ЭдС. Спецификация верна (хотя и сбивает с толку). Смотрите мой ответ ниже. - person Dylan Meador; 07.08.2012
comment
@Dylan: Ах, хороший улов! Я не думал, что это может быть вымышленный класс, используемый только для демонстрации. +1 - person Ed S.; 07.08.2012