“==” Оператор не Ведет себя Как сгенерированный Компилятором, Равняется () переопределению для анонимного типа

Согласно MSDN:

Поскольку методы Равняний и GetHashCode на анонимных типах определяются с точки зрения Равняния и GetHashcode свойств, два экземпляра того же анонимного типа равны, только если все их свойства равны.

Однако следующий код демонстрирует, что компилятор генерировал реализацию для Equals() не ведет себя как ожидалось.:

 DateTime start = new DateTime(2009,1,1);
 DateTime end = new DateTime(2010, 12,31);

 // months since year 0
 int startMonth = start.Date.Year * 12 + start.Date.Month - 1;
 int endMonth = end.Date.Year * 12 + end.Date.Month -1 ;

 // iterate through month-year pairs
 for (int i = startMonth; i <= endMonth ; i++)
 {
  var yearMonth = new { Year = (int)Math.Truncate(i/12d), Month = (i % 12) + 1};

  if (yearMonth.Year == 2009 &&  yearMonth.Month == 2)
   Console.WriteLine("BOOM");

  if (yearMonth == new{Year = 2009, Month = 2})
   Console.WriteLine("I'm never called!");

  Console.WriteLine(yearMonth);
 }

Я пропускаю что-то? Я смотрю на сгенерированный MSIL, но не вижу очевидной ошибки. Существует ли путь к уровню MSIL, отлаживающему (помимо WinDbg, возможно)? Я пропускаю что-то?

Я протестировал.NET 3.5 (компилятор SP1 VS 2008). Для ссылки вот сгенерированный, Равняется методу:

public override bool Equals(object value)
{
    var type = value as <>f__AnonymousType3<j__TPar, j__TPar>;
    return (((type != null) && EqualityComparer<j__TPar>.Default.Equals(this.i__Field, type.i__Field)) && EqualityComparer<j__TPar>.Default.Equals(this.i__Field, type.i__Field));
}

8
задан John Saunders 21 February 2010 в 21:33
поделиться

2 ответа

== не Equals () - Я считаю, что ваш код должен работать должным образом, когда вы делаете это:

if (yearMonth.Equals(new{Year = 2009, Month = 2}))

См. Также этот вопрос SO .

7
ответ дан 5 December 2019 в 12:58
поделиться

Lucero прав, но я хочу добавить объяснение того, почему это правильно.

Для ссылочных типов в .Net оператор == предназначен для указания ссылочного равенства; ссылаются ли две переменные на один и тот же экземпляр объекта?

Метод .Equals(), с другой стороны, предназначен для указания значения равенства; имеют ли два (возможно) разных экземпляра объекта одно и то же значение, для некоторого определения "одинакового", которое вам обычно разрешено давать для ваших типов?

6
ответ дан 5 December 2019 в 12:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: