1. 程式人生 > >21 C# 第十七章(三) 使用動態物件

21 C# 第十七章(三) 使用動態物件

使用動態物件

使用動態物件進行程式設計,開發人員可以用一個動態排程機制對設想的操作進行編碼。"執行時" 會在程式執行時對這個機制進行解析,而不是由編譯器在編譯時驗證和繫結。


一個簡單的例項 來自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檔案的程式碼要簡潔。

DynamicXml.cs
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