【发布时间】:2012-09-20 19:39:48
【问题描述】:
我一直在尝试LINQPad 中的一些 C# 语句,以了解发出了什么中间语言代码。
我首先尝试了以下代码:
var Container = new {Name = "James"};
Console.WriteLine(Container.Name);
看到下面六行IL发出:
IL_0001: ldstr "James"
IL_0006: newobj <>f__AnonymousType0<System.String>..ctor
IL_000B: stloc.0
IL_000C: ldloc.0
IL_000D: callvirt <>f__AnonymousType0<System.String>.get_Name
IL_0012: call System.Console.WriteLine
这大致符合我的预期,并且很好地展示了匿名类型如何是只读/不可变的,因为没有 set_Name 属性。
接下来我尝试了以下语句:
dynamic Container = new System.Dynamic.ExpandoObject();
Container.Name = "James";
Console.WriteLine(Container.Name);
这会导致大量的 IL 被释放。我不会在这里粘贴它,但你可以在this pastebin 中找到它。
我知道在管理动态类型和 ExpandoObject 方面有相当多的开销,但我不明白为什么在这种情况下对 System.Console.WriteLine 的调用似乎是通过内部反射执行的。
IL_0072: ldstr "WriteLine"
....
IL_00BF: ldtoken System.Console
在第一段代码中,属性被检索和存储后,是一行IL语句,调用了System.Console.WriteLine。
那么为什么dynamic 类型的调用需要所有这些额外的功能?
【问题讨论】:
标签: c# dynamic reflection compiler-construction il