// Выполнить рефлексию того, что сгенерировал компилятор.
ReflectOverAnonymousType(myCar);
...
Console.ReadLine;
Вывод будет выглядеть примерно так:
***** Fun with Anonymous Types *****
obj is an instance of: <>f__AnonymousType0`3
Base class of <>f__AnonymousType0`3 is System.Object
obj.ToString = { Color = Bright Pink, Make = Saab, CurrentSpeed = 55 }
obj.GetHashCode = -564053045
Первым делом обратите внимание в примере на то, что объект myCar
<>f__AnonymousType0`3 (в вашем выводе имя типа может быть другим). Помните, что имя, назначаемое типу, полностью определяется компилятором и не доступно в коде C# напрямую.Пожалуй, наиболее важно здесь то, что каждая пара "имя-значение", определенная с использованием синтаксиса инициализации объектов, отображается на идентично именованное свойство, доступное только для чтения, и соответствующее закрытое поддерживающее поле, которое допускает только инициализацию. Приведенный ниже код C# приблизительно отражает сгенерированный компилятором класс, применяемый для представления объекта myCar
ildasm.exe):private sealed class <>f__AnonymousType0'3'<'
'
extends [System.Runtime][System.Object]
{
// Поля только для инициализации.
private initonly
private initonly
private initonly
// Стандартный конструктор.
public <>f__AnonymousType0(
// Переопределенные методы.
public override bool Equals(object value);
public override int GetHashCode;
public override string ToString;
// Свойства только для чтения.
}
Реализация методов ToString и GetHashCode
Все анонимные типы автоматически являются производными от System.Object
Equals, GetHashCode и ToString. Реализация ToString просто строит строку из пар "имя-значение". Вот пример:public override string ToString
{
StringBuilder builder = new StringBuilder;
builder.Append("{ Color = ");
builder.Append(this.
builder.Append(", Make = ");
builder.Append(this.
builder.Append(", CurrentSpeed = ");
builder.Append(this.
builder.Append(" }");
return builder.ToString;
}
Реализация GetHashCode
System.Collections.Generic.EqualityComparer. С такой реализацией GetHashCode два анонимных типа будут выдавать одинаковые хеш-значения тогда (и только тогда), когда они обладают одним и тем же набором свойств, которым присвоены те же самые значения. Благодаря подобной реализации анонимные типы хорошо подходят для помещения внутрь контейнера Hashtable. Семантика эквивалентности анонимных типов
Наряду с тем, что реализация переопределенных методов ToString
GetHashCode прямолинейна, вас может интересовать, как был реализован метод Equals. Например, если определены две переменные "анонимных автомобилей" с одинаковыми наборами пар "имя-значение", то должны ли эти переменные считаться эквивалентными? Чтобы увидеть результат такого сравнения, дополните класс Program следующим новым методом:static void EqualityTest
{
// Создать два анонимных класса с идентичными наборами
// пар "имя-значение".
var firstCar = new { Color = "Bright Pink", Make = "Saab",
Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT