Я экспериментировал с некоторыми операторами C# в LINQPad, чтобы понять, какой код промежуточного языка генерируется.
Сначала я попробовал следующий код:
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. Я не буду вставлять его сюда, но вы можете найти его в этой вставке.
Я понимаю, что управление динамическим типом и ExpandoObject сопряжено с большими накладными расходами, но я не понимаю, почему вызов System.Console.WriteLine
в данном случае выполняется посредством внутреннего отражения.
IL_0072: ldstr "WriteLine"
....
IL_00BF: ldtoken System.Console
В первом сегменте кода, после извлечения и сохранения свойства, это был однострочный оператор IL, который вызывал System.Console.WriteLine
.
Так зачем же все это нужно для вызова с типом dynamic
?