2016-07-25 67 views
1

的幫助這樣說:Equals和GetHashCode如何在匿名類型上實現?

匿名類型是直接從object派生不能被強制轉換爲任何類型,除了對象類類型和 。編譯器爲每個匿名類型提供一個 名稱,儘管您的應用程序無法訪問 它。從公共語言運行時的角度來看,匿名的 類型與其他任何引用類型沒有區別。

如果在組裝兩個或更多個匿名對象初始化指定在相同的順序,並且具有相同 名稱和類型屬性的 序列,所述編譯器將對象作爲 相同類型的實例。它們共享編譯器生成的類型 信息。

由於上匿名類型的Equals和GetHashCode方法中的Equals和 性質的GetHashCode方法的術語被定義 ,相同的匿名類型的兩個實例是相等僅當所有 它們的性質是相同的。

這些事情是真的,但怎麼樣?參考源明確顯示如何比較對象(ReferenceEquals)和「直接從對象派生」的類型不能具有此特殊行爲。它與ValueType中的Equals的行爲不匹配。

那麼它是如何完成的?匿名類型如何覆蓋Equals()GetHashCode()而沒有任何可見的覆蓋?

+1

編譯器生成引用類型。我不知道你在「參考資料來源」(我認爲你的意思是微軟的參考源網站)中看到的是什麼,但它不會提供信息,因爲參考資源不可能有一種類型,直到你編譯你的代碼纔會生成。您應該在_your_匿名類型中尋找像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

很好的回答!搞定了。鏈接(與所有常見的嫌疑人)只是一個獎金。誰知道編譯器做了這麼多? –