簡體   English   中英

匿名類型C#

[英]Anonymous Types C#

我知道匿名類型沒有自己的預定義類型。 編譯器以編譯類型為其分配類型,並且在編譯時分配的類型的詳細信息無法在代碼級別知道; 這些細節是CLR本身所知的。 我聽說CLR上的這些匿名類型被視為僅僅是引用類型。 所以我的問題是,在編譯時是否創建了類似於類或結構的新類型,對應於匿名類型中定義的只讀屬性?

我知道匿名類型沒有自己的預定義類型。

正確。 除了匿名類型共有的對象之外,沒有其他基本類型。

編譯器以編譯類型為其分配類型,並且在編譯時分配的類型的詳細信息無法在代碼級別獲知

那是對的。

這些細節是CLR本身所知的。

我不知道你在談論什么“細節”或“CLR已知”的含義。

我聽說CLR上的這些匿名類型被視為僅僅是引用類型。

你沒聽錯。

所以我的問題是,在編譯時是否創建了類似於類或結構的新類型,對應於匿名類型中定義的只讀屬性?

是。 創建一個新類。

請注意, 在程序集中,如果有兩個具有相同屬性名稱,相同屬性類型的匿名類型,則按相同順序,則只創建一個類型。 這是由語言規范保證的。

行使:

// Code in Assembly B:
public class B { protected class P {} }

// Code in Assembly D (references assembly B)
class D1 : B { 
  public static object M() { return new { X = new B.P() }; }
}
class D2 : B { 
  public static object M() { return new { X = new B.P() }; }
}

您需要在程序集D中生成單個類聲明,該聲明具有BP類型的屬性X,使得D1.M().GetType()等於D2.M().GetType() 描述如何操作。

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

資料來源: https//msdn.microsoft.com/en-us/library/bb397696.aspx

除了沒有程序員可訪問的名稱之外,匿名類型非常簡單:編譯器根據您所做的分配生成它們,並負責將相同匿名類型從同一方法正確合並到單個運行時類型中。

根據C#語言規范,第7.6.10.6節,匿名類型總是類,而不是struct 表單的匿名對象初始值設定項

new { p1 = e1 , p2 = e2 , ... pn = en }

聲明表單的匿名類型

class __Anonymous1 {
    private readonly T1 f1 ;
    private readonly T2 f2 ;
    ...
    private readonly Tn fn ;
    public __Anonymous1(T1 a1, T2 a2,…, Tn an) {
        f1 = a1 ;
        f2 = a2 ;
        ...
        fn = an ;
    }
    public T1 p1 { get { return f1 ; } }
    public T2 p2 { get { return f2 ; } }
    ...
    public Tn pn { get { return fn ; } }
    public override bool Equals(object __o) { … }
    public override int GetHashCode() { … }
}

這些匿名類直接從對象派生。 通常,它們用於選擇LINQ查詢,以將只讀屬性封裝到單個對象中。

LINQ示例(FirstName和LastName作為FullName):

public class Person {
    public int Id {get;set;}
    public string FirstName {get;set;}
    public string LastName {get;set;}
}

IEnumerable<int> personIds = persons
    .Select(p => new { Id = p.Id, FullName = p.FirstName + " " + p.LastName})
    .Where(a => a.FullName == "John Smith")
    .Select(a => a.Id);

匿名類型是C♯功能,在CLI上沒有等效功能。 它們被簡單地編譯為普通類型,編譯器選擇了非常長且非常復雜的名稱。 請注意,規范保證具有相同結構的兩個匿名類型(在同一個程序集中)實際上是相同的類型,因此編譯器也需要考慮到這一點,並且只生成一個類型(並為兩者生成相同的名稱)使用網站)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM