Почему компилятор генерирует разные классы для анонимных типов, если порядок полей различен

Я рассмотрел 2 случая:

var a = new { a = 5 };
var b = new { a = 6 };
Console.WriteLine(a.GetType() == b.GetType()); // True

Идеал: http://ideone.com/F8QwHY

и

var a = new { a = 5, b = 7 };
var b = new { b = 7, a = 6 };
Console.WriteLine(a.GetType() == b.GetType()); // False

Идеал: http://ideone.com/hDTcxX

Вопрос в том, почему порядок полей действительно имеет значение?

Есть ли причина для этого или просто потому, что это (таков дизайн).

Если причина в том, что типы анонимов не должны использоваться таким образом, и вы не должны обращаться к GetType, то почему компилятор повторно использует один класс в первом случае, а не просто генерирует новый класс для каждого объявления типа анонимуса?

Ответ 1

Таким образом, причиной конструктивного решения было ToString. Анонимный тип возвращает другой код string, соответствующий порядку. Прочтите блог Эрика Липперта.

{ a = 5, b = 7 }
{ b = 7, a = 6 }

Демо-версия

Ответ 2

Спецификация языка С#, раздел 7.6.10.6, требует, чтобы последовательность свойств была одинаковой для того, чтобы анонимные типы считались идентичными:

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

В вашем втором примере первый анонимный класс имеет последовательность свойств {a, b}, а второй анонимный класс имеет последовательность {b, a}. Эти последовательности не считаются одинаковыми.

Ответ 3

Вы ведете к тому, что я предполагаю, причина в том, что типы анонимны, поэтому в зависимости от GetType() для возврата надежных результатов это ужасная идея.

Что касается того, почему компилятор повторно использует тип, если порядок совпадает, я угадываю его просто для экономии времени и пространства. Когда вы принимаете во внимание заказ, гораздо легче кэшировать сгенерированные классы во время компиляции, а затем повторно использовать их при необходимости.