c#3.0系列:Anonymous Type In CLR(3.5)

我们说Anonymous Type是C# 3.0的新的特性,而没有说Anonymous Type是.NET Framework 3.5的新特性。这是因为Anonymous Type仅仅是.NET Programming Language和相应的Compiler的新引入的特征。而对于.NET Framework 3.5来说,它看不到这和原来有什么不同,对于Anonymous Type和一般的Named Type,对于CLR来说他们之间没有什么本质的区别。
通过下面这样的一段简单的代码:

1 var p1  =   new   { Name = "IORI", Age = 27 } ;
然后我们再看看IL:
Code
 1.method private hidebysig static void  Main(string[] args) cil managed
 2{
 3  .entrypoint
 4  // Code size       15 (0xf)
 5  .maxstack  3
 6  .locals init ([0class '<>f__AnonymousType0`2'<string,int32> p1)
 7  IL_0000:  nop
 8  IL_0001:  ldstr      "IORI"
 9  IL_0006:  ldc.i4.s   27
10  IL_0008:  newobj     instance void class '<>f__AnonymousType0`2'<string,int32>::.ctor(!0,
11                                                                                        !1)
12  IL_000d:  stloc.0
13  IL_000e:  ret
14// end of method Program::Main
15
我们再这里就可以看出Compiler将会为p1这个Anonymous Type创建一个名为 <>f__AnonymousType0`2 < string , int32 >的类型。参数将根据数据成员的具体结构,这里也是声明一个类型。这个类继承自object,并且重写了ToString() 和 GetHashCode()的实现。所有的匿名类型自动继承自System.Object ,并且重写了Equals(), GetHashCode(), and ToString(). 如下图:

结构如下:
internal sealed  class  <>f__AnonymousType0<<Name>j__TPar, <Age>j__TPar>
{
    
//  Fields    
private  readonly <Age>j__TPar <Age>i__Field;
        
private  readonly <Name>j__TPar <Name>i__Field;

    
//  Methods    
public  <>f__AnonymousType0(<Name>j__TPar Name, <Age>j__TPar Age);
    
    
public  override  bool  Equals( object  value);
        
public  override int GetHashCode();
        
public  override  string  ToString();

    
//  Properties
     public  <Age>j__TPar Age { get; }
    
public  <Name>j__TPar Name { get; }
}
再看看下面的例子。
Code
 1class Program
 2    {
 3        static void Main(string[] args)
 4        {
 5            var p1 = new { Name = "IORI", Age = 27 };
 6            var p2 = new { Name = "IORI", Age = 27 };
 7            var p3 = new { Name = "GUOJUN", Age = 27 };
 8            var p4 = new person { Name = "GUOJUN", Age = 27 };
 9            Console.WriteLine("Base class of {0} is {1}", p1.GetType().Name, p1.GetType().BaseType);
10            Console.WriteLine("p1.ToString() = {0}", p1.ToString());
11            Console.WriteLine("p1.GetType() = {0}", p1.GetType());
12            Console.WriteLine("p3.GetType() = {0}", p3.GetType());
13            Console.WriteLine("p4.GetType() = {0}", p4.GetType());
14            Console.WriteLine("p1.GetHashCode() = {0}", p1.GetHashCode());
15            Console.WriteLine("(p1.GetHashCode() == p2.GetHashCode())= {0}", p1.GetHashCode() == p2.GetHashCode());
16            Console.WriteLine("(p1.GetHashCode() == p3.GetHashCode())= {0}", p1.GetHashCode() == p3.GetHashCode());
17            Console.WriteLine("p1.Equals(p2)= {0}", p1.Equals(p2));
18            Console.WriteLine("p1.Equals(p3)= {0}", p1.Equals(p3));
19            Console.WriteLine("p3.Equals(p4)= {0}", p3.Equals(p4));
20            Console.WriteLine("(p1 == p2)= {0}", p1 == p2);
21            Console.WriteLine("object.ReferenceEquals(p1.GetType(),p2.GetType()) = {0}"object.ReferenceEquals(p1.GetType(), p2.GetType()));
22            Console.WriteLine("object.ReferenceEquals(p1.GetType(),p3.GetType()) = {0}"object.ReferenceEquals(p1.GetType(), p3.GetType()));
23            Console.WriteLine("object.ReferenceEquals(p3.GetType(),p4.GetType()) = {0}"object.ReferenceEquals(p3.GetType(), p4.GetType()));
24            Console.Read();
25        }

26    }

27
28    class person
29    {
30        public int Age {get;set;}
31        public string Name {getset;}
32    }

33
我们看看输出的结果。

通过以上的结果我们更能对Compiler会为Anonymous Type创建的类型更好的理解。
GetHashCode()   实现时,根据匿名类型的每个成员作为System.Collections.Generic.EqualityComparer<T>的输入,来计算hash值。因此,如果2个匿名类型有相同的属性字段,同时每个字段的值也相同,那么生成的Hash值也就相等。
ToString()   只是简单的用 属性名称/属性值 构造了一个字符串。
Equals()      结果相等,因为它使用值来比较相等。
==             结果不等,因为匿名类型没有重载 == 和 != , 这两个操作符默认情况下,比较的是对象的引用而不是值。
总结:
• Anonymous types 继承 System.Object.
• The fields and properties 是read-only.
• Anonymous types 不支持events, custom methods, custom operators, or custom overrides.
• Anonymous types 是个密封类.
• Anonymous types 用自己定义的构造方法(不可以修改)来创建的.
最重要的是
Compiler在生成Anonymous types 的时候,并不是为每个如{N=?, N2 =? , ...}的结构生成一个不同的Type,它只会为不同的参数列表的结构: 参数的名称,参数的数据类型,参数的相互顺序定义不同的Type(不包含参数的值)。而具有相同的参数列表的{N=?, N2 =? , ...}会共享同一个Type。但是这种仅限于在同一个Assembly中,编译器只会生成一个匿名类型,这些对象都是该唯一的匿名类型的实例。
在同一个程序集内,两个匿名对象具有相同的属性、相同的属性顺序。编译器将认为这两个匿名对象是相同的。

转载于:https://www.cnblogs.com/gjcn/archive/2008/04/09/1144851.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值