65.9K
CodeProject 正在变化。 阅读更多。
Home

匿名类型

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.62/5 (12投票s)

2010年12月6日

CPOL

1分钟阅读

viewsIcon

69978

匿名类型

什么是匿名类型? 匿名类型是 C# 3.0 中的新概念,允许创建新的类型而无需定义它们。为什么在 C# 中引入匿名类型? 匿名类型被引入是为了支持一个非常有用的特性,称为 LINQ。 当您使用 LINQ 查询对象集合,并且只想返回其中的几个属性时,它最有用。如何定义匿名类型? 可以使用 C# 的 new 关键字轻松定义匿名类型。 以下是示例:
var pranay = new { id=1, Name= "pranay rana" };
var krunal = new { id=1, Name= "krunal mevada" };

LINQ 查询示例

查询具有 Id、Name 和 Age 属性的对象集合,但您只想在查询数据后获取 Id 和 Name,那么代码如下:
var user = from user in Users
                select new { user.Name, user.Id}
正如您所见,select new 即代码的第二行生成了匿名类型。 考虑下面的代码以更详细地了解匿名类型。 要定义匿名类型的数组:
var persons = new[] { 
               new { id=1, Name= "pranay rana" },
               new { id=2, Name= "krunal mevada" },
               new { id=3, Name= "hemang vyas" } 
             };

          foreach (var person in persons)
            {
                Console.WriteLine("Person : " + person.id);
                Console.WriteLine("Person : " + person.Name);
            }
编译代码后,当您在 ILDASM 中查看 DLL 或 EXE 文件时,它会显示编译器生成的代码。
代码行定义了由编译器生成的匿名类型
locals init ([0] class '<>f__AnonymousType0`2'<int32,string>[] persons,
           [1] class '<>f__AnonymousType0`2'<int32,string> person,
           [2] class '<>f__AnonymousType0`2'<int32,string>[] CS$0$0000,
           [3] class '<>f__AnonymousType0`2'<int32,string>[] CS$6$0001,
           [4] int32 CS$7$0002,
           [5] bool CS$4$0003)
该类型的数组定义如下:
IL_0000:  nop
  IL_0001:  ldc.i4.3
  IL_0002:  newarr     class '<>f__AnonymousType0`2'<int32,string>
创建匿名类型的实例
IL_0015:  stelem.ref
  IL_0016:  ldloc.2
  IL_0017:  ldc.i4.1
  IL_0018:  ldc.i4.2
  IL_0019:  ldstr      "krunal mevada"
  IL_001e:  newobj     instance void class '<>f__AnonymousType0`2'<int32,string>::.ctor(!0,
                                                                                        !1)
完整源代码
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       136 (0x88)
  .maxstack  5
  .locals init ([0] class '<>f__AnonymousType0`2'<int32,string>[] persons,
           [1] class '<>f__AnonymousType0`2'<int32,string> person,
           [2] class '<>f__AnonymousType0`2'<int32,string>[] CS$0$0000,
           [3] class '<>f__AnonymousType0`2'<int32,string>[] CS$6$0001,
           [4] int32 CS$7$0002,
           [5] bool CS$4$0003)
  IL_0000:  nop
  IL_0001:  ldc.i4.3
  IL_0002:  newarr     class '<>f__AnonymousType0`2'<int32,string>
  IL_0007:  stloc.2
  IL_0008:  ldloc.2
  IL_0009:  ldc.i4.0
  IL_000a:  ldc.i4.1
  IL_000b:  ldstr      "pranay rana"
  IL_0010:  newobj     instance void class '<>f__AnonymousType0`2'<int32,string>::.ctor(!0,
                                                                                        !1)
  IL_0015:  stelem.ref
  IL_0016:  ldloc.2
  IL_0017:  ldc.i4.1
  IL_0018:  ldc.i4.2
  IL_0019:  ldstr      "krunal mevada"
  IL_001e:  newobj     instance void class '<>f__AnonymousType0`2'<int32,string>::.ctor(!0,
                                                                                        !1)
  IL_0023:  stelem.ref
  IL_0024:  ldloc.2
  IL_0025:  ldc.i4.2
  IL_0026:  ldc.i4.3
  IL_0027:  ldstr      "hemang vyas"
  IL_002c:  newobj     instance void class '<>f__AnonymousType0`2'<int32,string>::.ctor(!0,
                                                                                        !1)
  IL_0031:  stelem.ref
  IL_0032:  ldloc.2
  IL_0033:  stloc.0
  IL_0034:  nop
  IL_0035:  ldloc.0
  IL_0036:  stloc.3
  IL_0037:  ldc.i4.0
  IL_0038:  stloc.s    CS$7$0002
  IL_003a:  br.s       IL_007a
  IL_003c:  ldloc.3
  IL_003d:  ldloc.s    CS$7$0002
  IL_003f:  ldelem.ref
  IL_0040:  stloc.1
  IL_0041:  nop
  IL_0042:  ldstr      "Person : "
  IL_0047:  ldloc.1
  IL_0048:  callvirt   instance !0 class '<>f__AnonymousType0`2'<int32,string>::get_id()
  IL_004d:  box        [mscorlib]System.Int32
  IL_0052:  call       string [mscorlib]System.String::Concat(object,
                                                              object)
  IL_0057:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_005c:  nop
  IL_005d:  ldstr      "Person : "
  IL_0062:  ldloc.1
  IL_0063:  callvirt   instance !1 class '<>f__AnonymousType0`2'<int32,string>::get_Name()
  IL_0068:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
  IL_006d:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0072:  nop
  IL_0073:  nop
  IL_0074:  ldloc.s    CS$7$0002
  IL_0076:  ldc.i4.1
  IL_0077:  add
  IL_0078:  stloc.s    CS$7$0002
  IL_007a:  ldloc.s    CS$7$0002
  IL_007c:  ldloc.3
  IL_007d:  ldlen
  IL_007e:  conv.i4
  IL_007f:  clt
  IL_0081:  stloc.s    CS$4$0003
  IL_0083:  ldloc.s    CS$4$0003
  IL_0085:  brtrue.s   IL_003c
  IL_0087:  ret
} // end of method Program::Main
关于匿名类型的快速事实
  • 匿名类型是派生自 system.objects 的引用类型。
  • 匿名类型的属性是只读的。
  • 如果两个匿名类型具有相同的属性和相同的顺序,则编译器将它们视为相同的类型,但前提是它们都在同一个程序集中。
  • 匿名类型具有方法作用域。 如果您想从方法返回匿名类型,则必须将其转换为对象类型。 但这不是一个好的做法。
更多信息请访问:http://pranayamr.blogspot.com/
© . All rights reserved.