2016-07-25 9 views
1

도움말이 말한다 :익명 형식에서 Equals 및 GetHashCode는 어떻게 구현됩니까?

익명 유형의 객체를 제외한 모든 유형으로 변환 할 수없는 클래스 객체에서 직접 파생 유형 및 있습니다. 컴파일러는 각 익명 유형에 이름을 제공하지만 응용 프로그램에서는 에 액세스 할 수 없습니다. 공용 언어 런타임의 관점에서 익명의 형식은 다른 참조 형식과 다를 수 있습니다.

어셈블리의 두 개 이상의 익명 개체 초기화 같은 순서에있는 즉 동일한 명칭 및 유형을 등록하는 시퀀스를 지정하는 경우에는, 컴파일러 동일한 유형의 인스턴스로서 오브젝트를 처리한다. 동일한 컴파일러 생성 유형 정보를 공유합니다. 익명의 종류에 같고를 GetHashCode 방법이 등호와 등록 정보를 GetHashCode 방법으로 정의되므로

동일한 익명 유형의 두 인스턴스 모든 속성이 동일한 경우에만 동일하다.

이러한 사항은 사실이지만 어떻게됩니까? 참조 소스는 객체가 어떻게 비교되는지 (ReferenceEquals), '객체에서 직접 파생 된'유형은이 특별한 동작을 수행 할 수 없습니다. ValueType에있는 Equals의 동작과 일치하지 않습니다.

어떻게 완료 되었습니까? 익명 형식은 눈에 띄는 재정의없이 Equals()GetHashCode()을 어떻게 재정의 할 수 있습니까?

+1

컴파일러에서 참조 형식을 생성합니다. 나는 당신이 "참고 자료"(당신이 Microsoft의 참고 자료 웹 사이트를 의미한다고 가정)에서 당신이 무엇을보고 있는지 알지 못하지만, 참고 자료가 그 유형을 가질 수있는 방법이 없기 때문에 유익하지 않을 것이다. 코드를 컴파일 할 때까지 생성되지 않습니다. 익명 타입에서 ILDASM, dotPeek, Reflector 등과 같은 것을 살펴 봐야한다. 거기에서 메소드의 구현을 볼 수있다. –

답변

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

좋은 답변입니다! 그것을 찔렀다. 링크 (모든 용의자와)는 단지 보너스였습니다. 컴파일러가 그렇게 많이 알았던 사람은 누구입니까? –