I've been playing around with some C# statements in LINQPad with a view to understanding what intermediate language code is emitted.
I first tried the following code:
var Container = new {Name = "James"};
Console.WriteLine(Container.Name);
And saw the following six lines of IL emitted:
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
Which, is broadly what I expect, and is quite a nice demonstration of how anonymous types are read-only/immutable, seeing as there is no set_Name property.
Next I tried the statements:
dynamic Container = new System.Dynamic.ExpandoObject();
Container.Name = "James";
Console.WriteLine(Container.Name);
Which causes a huge amount of IL to be emitted. I'll not paste it here, but you can find it in this pastebin.
I understand there is quite a bit of overhead with regard to managing the dynamic type and ExpandoObject, but I don't understand why it appears that the call to System.Console.WriteLine
is in this case performed through internal reflection.
IL_0072: ldstr "WriteLine"
....
IL_00BF: ldtoken System.Console
In the first segment of code, after the property was retrieved and stored, it was a one-line IL statement that invoked System.Console.WriteLine
.
So why is all this extra required for the call with a dynamic
type?