21 C# 第十七章(三) 使用動態物件
阿新 • • 發佈:2019-02-01
使用動態物件
使用動態物件進行程式設計,開發人員可以用一個動態排程機制對設想的操作進行編碼。"執行時" 會在程式執行時對這個機制進行解析,而不是由編譯器在編譯時驗證和繫結。一個簡單的例項 來自MSDN
using System; namespace DynamicExamples { class Program { static void Main(string[] args) { ExampleClass ec = new ExampleClass(); Console.WriteLine(ec.exampleMethod(10)); Console.WriteLine(ec.exampleMethod("value")); //************************** Point 1 ************************** // The following line causes a compiler error because exampleMethod // takes only one argument. //Console.WriteLine(ec.exampleMethod(10, 4)); //*************************************************************** dynamic dynamic_ec = new ExampleClass(); Console.WriteLine(dynamic_ec.exampleMethod(10)); //************************** Point 2 ************************** // Because dynamic_ec is dynamic, the following call to exampleMethod // with two arguments does not produce an error at compile time. // However, itdoes cause a run-time error. //Console.WriteLine(dynamic_ec.exampleMethod(10, 4)); //*************************************************************** Console.ReadKey(); } } class ExampleClass { //static dynamic field; dynamic prop { get; set; } public dynamic exampleMethod(dynamic d) { dynamic local = "Local variable"; int two = 2; if (d is int) { return local; } else { return two; } } } }
注意註釋的重點的兩行,雖然被註釋了但意義重大。
在point 1使用的是基礎型別,如果發現被呼叫的類的成員不存在編譯時就會報錯。在point 2使用的是dynamic型別,如果發現被呼叫的類的成員不存在會在執行時丟擲異常。
如果一變數宣告為dynamic,編譯時不會檢查指定的成員是否存在,甚至不會檢查dynamic的基礎型別是什麼。
但dynamic型別在執行時發現呼叫的成員不存在,則會引發 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException。
使用dynamic的好處
這裡有一個解析XML檔案的小例子,它包含了兩部分,自定義的一個dynamic型別和使用它,尤其在使用它的時候,他比正常的解析XML檔案的程式碼要簡潔。
using System; using System.Collections.Generic; using System.Linq; using System.Dynamic; using System.Xml.Linq; namespace dyanmic_parse_xml { public class DynamicXml : DynamicObject { private XElement Element{get; set;} public DynamicXml(XElement element) { Element = element; } public static DynamicXml Parse(string str) { return new DynamicXml(XElement.Parse(str)); } public override bool TryGetMember(GetMemberBinder binder, out object result) { bool success = false; result = null; XElement firstDescendant = Element.Descendants(binder.Name).FirstOrDefault(); if (firstDescendant != null) { if (firstDescendant.Descendants().Count() > 0) { result = new DynamicXml(firstDescendant); } else { result = firstDescendant.Value; } success = true; } return success; } public override bool TrySetMember(SetMemberBinder binder, object value) { bool success = false; XElement firstDescendant = Element.Descendants(binder.Name).FirstOrDefault(); if (firstDescendant != null) { if (value.GetType() == typeof(XElement)) { firstDescendant.ReplaceWith(value); } else { firstDescendant.Value = value.ToString(); } success = true; } return success; } } }
Program.cs
using System;
using System.Linq;
using System.Xml.Linq;
namespace dyanmic_parse_xml
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Use legacy way");
Console.WriteLine("=========================================================");
XElement person = XElement.Parse(@"<Person>
<FirstName>Inigo</FirstName>
<LastName>Montoya</LastName>
</Person>");
Console.WriteLine("{0} {1}", person.Descendants("FirstName").FirstOrDefault().Value,
person.Descendants("LastName").FirstOrDefault().Value);
Console.WriteLine("\nUse dynamic way");
Console.WriteLine("=========================================================");
dynamic dy_person = DynamicXml.Parse(@"<Person>
<FirstName>Inigo</FirstName>
<LastName>Montoya</LastName>
</Person>");
Console.WriteLine("{0} {1}", dy_person.FirstName,
dy_person.LastName);
Console.ReadKey();
}
}
}
dynamic的原則和行為
dynamic是告訴編譯器生成程式碼的指令。
dynamic 涉及到一個解釋機制。當"執行時"遇到dynamic呼叫時,他可以請求編譯成CIL,然後重新呼叫新編譯的呼叫。將型別指定為dynamic後,概念上是包裝了原始型別,這樣一來便不會有編譯時的驗證了。任何型別都會轉換成dynamic
從dynamic到一個替代型別的成功轉換要依賴於基礎型別的支援
從dynamic到一個標準CLR型別的轉換是一個顯式的轉型。dynamic的基礎型別在每次賦值時都可能改變
隱式型別變數(var)不能重新賦值成一個不同的型別,但dynamic則可以。dynamic涉及到一個解釋機制,它會先編譯再執行,所以它可以賦值成不同的型別。驗證基礎型別上是否存在指定的簽名推遲到執行時執行 ---- 但至少會執行
任何dynamic成員呼叫返回的都是dynamic物件對dynamic任何成員的呼叫都將返回一個dynamic物件,例如dynamic data.ToString()不會返回String而是返回一dynamic物件。
如果指定的成員在執行時不存在,"執行時"會引發Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
究其根本,dynamic是一個System.Object型別。
任何物件都能轉換為dynamic,dynamic也能顯式的轉換為不同物件的型別。它在行為上就像System.Object。但dynamic特殊的動態行為只在呼叫時才會出現,這是將它和System.Object區分開的關鍵。dynamic 使用ILDASM揭祕
dynamic執行時, .NetFramework在幕後會使用反射來查詢成員並驗證簽名是否匹配。然後"執行時"生成一個表示式樹,它代表由呼叫點定義的動態表示式。表示式樹編譯好後,我們就得到了和本來應該由編譯器生成的結果相似的CIL結果。然後,這些CIL程式碼被"注入"呼叫點,並通過委託來實際的呼叫。由於CIL現已注入呼叫點,所以後續的呼叫不會再產生反射和編譯開銷。使用 ILDASM 打開了第一個例項程式。但在段CIL程式碼中在呼叫dynamic物件時它的程式碼和使用正常物件的程式碼差不多。
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 451 (0x1c3)
.maxstack 11
.locals init ([0] class DynamicExamples.ExampleClass ec,
[1] object dynamic_ec,
[2] class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[] CS$0$0000)
IL_0000: nop
IL_0001: newobj instance void DynamicExamples.ExampleClass::.ctor()
IL_0006: stloc.0
IL_0007: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
IL_000c: brtrue.s IL_0051
IL_000e: ldc.i4 0x100
IL_0013: ldstr "WriteLine"
IL_0018: ldnull
IL_0019: ldtoken DynamicExamples.Program
IL_001e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0023: ldc.i4.2
IL_0024: newarr [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo
IL_0029: stloc.2
IL_002a: ldloc.2
IL_002b: ldc.i4.0
IL_002c: ldc.i4.s 33
IL_002e: ldnull
IL_002f: call class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
string)
IL_0034: stelem.ref
IL_0035: ldloc.2
IL_0036: ldc.i4.1
IL_0037: ldc.i4.0
IL_0038: ldnull
IL_0039: call class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
string)
IL_003e: stelem.ref
IL_003f: ldloc.2
IL_0040: call class [System.Core]System.Runtime.CompilerServices.CallSiteBinder [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::InvokeMember(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,
string,
class [mscorlib]System.Collections.Generic.IEnumerable`1<class [mscorlib]System.Type>,
class [mscorlib]System.Type,
class [mscorlib]System.Collections.Generic.IEnumerable`1<class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)
IL_0045: call class [System.Core]System.Runtime.CompilerServices.CallSite`1<!0> class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder)
IL_004a: stsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
IL_004f: br.s IL_0051
IL_0051: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
IL_0056: ldfld !0 class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>>::Target
IL_005b: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
IL_0060: ldtoken [mscorlib]System.Console
IL_0065: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_006a: ldloc.0
IL_006b: ldc.i4.s 10
IL_006d: box [mscorlib]System.Int32
IL_0072: callvirt instance object DynamicExamples.ExampleClass::exampleMethod(object)
IL_0077: callvirt instance void class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>::Invoke(!0,
!1,
!2)
IL_007c: nop
IL_007d: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
IL_0082: brtrue.s IL_00c7
IL_0084: ldc.i4 0x100
IL_0089: ldstr "WriteLine"
IL_008e: ldnull
IL_008f: ldtoken DynamicExamples.Program
IL_0094: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0099: ldc.i4.2
IL_009a: newarr [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo
IL_009f: stloc.2
IL_00a0: ldloc.2
IL_00a1: ldc.i4.0
IL_00a2: ldc.i4.s 33
IL_00a4: ldnull
IL_00a5: call class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
string)
IL_00aa: stelem.ref
IL_00ab: ldloc.2
IL_00ac: ldc.i4.1
IL_00ad: ldc.i4.0
IL_00ae: ldnull
IL_00af: call class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
string)
IL_00b4: stelem.ref
IL_00b5: ldloc.2
IL_00b6: call class [System.Core]System.Runtime.CompilerServices.CallSiteBinder [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::InvokeMember(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,
string,
class [mscorlib]System.Collections.Generic.IEnumerable`1<class [mscorlib]System.Type>,
class [mscorlib]System.Type,
class [mscorlib]System.Collections.Generic.IEnumerable`1<class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)
IL_00bb: call class [System.Core]System.Runtime.CompilerServices.CallSite`1<!0> class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder)
IL_00c0: stsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
IL_00c5: br.s IL_00c7
IL_00c7: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
IL_00cc: ldfld !0 class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>>::Target
IL_00d1: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
IL_00d6: ldtoken [mscorlib]System.Console
IL_00db: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_00e0: ldloc.0
IL_00e1: ldstr "value"
IL_00e6: callvirt instance object DynamicExamples.ExampleClass::exampleMethod(object)
IL_00eb: callvirt instance void class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>::Invoke(!0,
!1,
!2)
IL_00f0: nop
IL_00f1: newobj instance void DynamicExamples.ExampleClass::.ctor()
IL_00f6: stloc.1
IL_00f7: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site3'
IL_00fc: brtrue.s IL_0141
IL_00fe: ldc.i4 0x100
IL_0103: ldstr "WriteLine"
IL_0108: ldnull
IL_0109: ldtoken DynamicExamples.Program
IL_010e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0113: ldc.i4.2
IL_0114: newarr [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo
IL_0119: stloc.2
IL_011a: ldloc.2
IL_011b: ldc.i4.0
IL_011c: ldc.i4.s 33
IL_011e: ldnull
IL_011f: call class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
string)
IL_0124: stelem.ref
IL_0125: ldloc.2
IL_0126: ldc.i4.1
IL_0127: ldc.i4.0
IL_0128: ldnull
IL_0129: call class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
string)
IL_012e: stelem.ref
IL_012f: ldloc.2
IL_0130: call class [System.Core]System.Runtime.CompilerServices.CallSiteBinder [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::InvokeMember(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,
string,
class [mscorlib]System.Collections.Generic.IEnumerable`1<class [mscorlib]System.Type>,
class [mscorlib]System.Type,
class [mscorlib]System.Collections.Generic.IEnumerable`1<class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)
IL_0135: call class [System.Core]System.Runtime.CompilerServices.CallSite`1<!0> class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder)
IL_013a: stsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site3'
IL_013f: br.s IL_0141
IL_0141: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site3'
IL_0146: ldfld !0 class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>>::Target
IL_014b: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site3'
IL_0150: ldtoken [mscorlib]System.Console
IL_0155: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_015a: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`4<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site4'
IL_015f: brtrue.s IL_019f
IL_0161: ldc.i4.0
IL_0162: ldstr "exampleMethod"
IL_0167: ldnull
IL_0168: ldtoken DynamicExamples.Program
IL_016d: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0172: ldc.i4.2
IL_0173: newarr [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo
IL_0178: stloc.2
IL_0179: ldloc.2
IL_017a: ldc.i4.0
IL_017b: ldc.i4.0
IL_017c: ldnull
IL_017d: call class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
string)
IL_0182: stelem.ref
IL_0183: ldloc.2
IL_0184: ldc.i4.1
IL_0185: ldc.i4.3
IL_0186: ldnull
IL_0187: call class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
string)
IL_018c: stelem.ref
IL_018d: ldloc.2
IL_018e: call class [System.Core]System.Runtime.CompilerServices.CallSiteBinder [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::InvokeMember(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,
string,
class [mscorlib]System.Collections.Generic.IEnumerable`1<class [mscorlib]System.Type>,
class [mscorlib]System.Type,
class [mscorlib]System.Collections.Generic.IEnumerable`1<class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)
IL_0193: call class [System.Core]System.Runtime.CompilerServices.CallSite`1<!0> class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`4<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,object>>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder)
IL_0198: stsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`4<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site4'
IL_019d: br.s IL_019f
IL_019f: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`4<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site4'
IL_01a4: ldfld !0 class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`4<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,object>>::Target
IL_01a9: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`4<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,object>> DynamicExamples.Program/'<Main>o__SiteContainer0'::'<>p__Site4'
IL_01ae: ldloc.1
IL_01af: ldc.i4.s 10
IL_01b1: callvirt instance !3 class [mscorlib]System.Func`4<class [System.Core]System.Runtime.CompilerServices.CallSite,object,int32,object>::Invoke(!0,
!1,
!2)
IL_01b6: callvirt instance void class [mscorlib]System.Action`3<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,object>::Invoke(!0,
!1,
!2)
IL_01bb: nop
IL_01bc: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_01c1: pop
IL_01c2: ret
} // end of method Program::Main