繁体   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