2016-07-25 15 views
1

справки говорит, что это:Каким образом Equals и GetHashCode реализованы на анонимных типах?

типы Анонимные типы класса, которые вытекают непосредственно из объекта, и , которые не могут быть отлиты любого типа, кроме объекта. Компилятор предоставляет имя для каждого анонимного типа, хотя ваше приложение не может получить доступ к . С точки зрения времени выполнения общего языка анонимный тип ничем не отличается от любого другого ссылочного типа.

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

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

Эти вещи верны, но как? Источник ссылки показывает явно, как сравниваются объекты (ReferenceEquals), и тип, «получаемый непосредственно из объекта», не может иметь этого особого поведения. Это не соответствует поведению Equals в ValueType.

Так как это делается? Как анонимные типы переопределяют Equals() и GetHashCode() без видимых переопределений?

+1

Компилятор генерирует ссылочные типы. Я не знаю, на что вы смотрите в «исходном источнике» (я полагаю, вы имеете в виду веб-сайт справочного источника Microsoft), но он не будет информативным, потому что источник ссылок не может иметь тип, который не работает 't генерируется, пока вы не скомпилируете свой код. Вы должны посмотреть что-то вроде ILDASM, dotPeek, Reflector и т. Д. В _your_ анонимных типах, и там вы увидите реализации методов. –

ответ

4

Компилятор генерирует GetHashCode() и Equals() переопределяет для вас. Например, из этого кода:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var a = new { Text = "foo", Value = 17 }; 

     Console.WriteLine(a); 
    } 
} 

Вы можете найти сгенерированный анонимный тип в скомпилированный EXE-файл, где методы выглядеть следующим образом (это выход из dotPeek & hellip; есть также ToString()):

[DebuggerHidden] 
    public override string ToString() 
    { 
    StringBuilder stringBuilder = new StringBuilder(); 
    stringBuilder.Append("{ Text = "); 
    stringBuilder.Append((object) this.\u003CText\u003Ei__Field); 
    stringBuilder.Append(", Value = "); 
    stringBuilder.Append((object) this.\u003CValue\u003Ei__Field); 
    stringBuilder.Append(" }"); 
    return ((object) stringBuilder).ToString(); 
    } 

    [DebuggerHidden] 
    public override bool Equals(object value) 
    { 
    var fAnonymousType0 = value as \u003C\u003Ef__AnonymousType0<\u003CText\u003Ej__TPar, \u003CValue\u003Ej__TPar>; 
    return fAnonymousType0 != null && EqualityComparer<\u003CText\u003Ej__TPar>.Default.Equals(this.\u003CText\u003Ei__Field, fAnonymousType0.\u003CText\u003Ei__Field) && EqualityComparer<\u003CValue\u003Ej__TPar>.Default.Equals(this.\u003CValue\u003Ei__Field, fAnonymousType0.\u003CValue\u003Ei__Field); 
    } 

    [DebuggerHidden] 
    public override int GetHashCode() 
    { 
    return -1521134295 * (-1521134295 * 512982588 + EqualityComparer<\u003CText\u003Ej__TPar>.Default.GetHashCode(this.\u003CText\u003Ei__Field)) + EqualityComparer<\u003CValue\u003Ej__TPar>.Default.GetHashCode(this.\u003CValue\u003Ei__Field); 
    } 

Связанные чтения:
How does ToString on an anonymous type work?
Why anonymous types Equals implementation compares fields?
Equality for anonymous types
Why is ValueType.GetHashCode() implemented like it is?

Ни один из этих вопросов не касается вашего вопроса, но они дают некоторое представление о конкретных реализациях этих переопределений.

+0

Отличный ответ! Успешно справился. Ссылки (со всеми обычными подозреваемыми) были просто бонусом. Кто знал, что компилятор сделал так много? –

 Смежные вопросы

  • Нет связанных вопросов^_^