匿名类型






4.62/5 (12投票s)
匿名类型
什么是匿名类型? 匿名类型是 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 的引用类型。
- 匿名类型的属性是只读的。
- 如果两个匿名类型具有相同的属性和相同的顺序,则编译器将它们视为相同的类型,但前提是它们都在同一个程序集中。
- 匿名类型具有方法作用域。 如果您想从方法返回匿名类型,则必须将其转换为对象类型。 但这不是一个好的做法。