VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Objective-C编程 >
  • c#3.0系列Anonymous type in CLR3.5

制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
 

  我们说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来说他们之间没有什么本质的区别。

  通过下面这样的一段简单的代码:

1var 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 ([0] class '<>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(). 如下图:

 

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

  结构如下:

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 {get; set;}
32  }
33

 

  我们看看输出的结果。

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

  通过以上的结果我们更能对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中,编译器只会生成一个匿名类型,这些对象都是该唯一的匿名类型的实例。

 

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

  结构如下:

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 {get; set;}
32  }
33



相关教程