Dynamic 编程;“动态”;输入C#

Dynamic 编程;“动态”;输入C#,dynamic,boxing,unboxing,Dynamic,Boxing,Unboxing,当我们在对象类型上使用动态类型时 我们能否克服头顶上的装箱/拆箱问题 void Print(dynamic p) { Console.WriteLine(string.Format("{0} : {1}", p.GetType(),p)); } void Print(object p) { Console.WriteLine(string.Format("{0} : {1}", p.GetType(),p)); } 从这两种方法来看,哪种方法对处理者来说既高效又友好?可能

当我们在对象类型上使用动态类型时

我们能否克服头顶上的装箱/拆箱问题

void Print(dynamic p)
{
     Console.WriteLine(string.Format("{0} : {1}", p.GetType(),p));
}

void Print(object p)
{
     Console.WriteLine(string.Format("{0} : {1}", p.GetType(),p));
}

从这两种方法来看,哪种方法对处理者来说既高效又友好?

可能根本没有区别。来自Microsoft:

在大多数情况下,类型动态的行为与类型对象类似。然而, 不解析包含dynamic类型表达式的操作 或由编译器检查的类型


由此我推断,在表达式中使用dynamic之前,dynamic将充当对象。这包括参数传递。

就装箱而言,这没有什么区别。以下面的代码为例:

public class TestClass
{
    static void Test()
    {
        int v = 5;    // Create an unboxed value type variable
        PrintDynamic(v);
    }

    static void PrintDynamic(dynamic p)
    {

    }
}
如果我将方法
Test()
反编译到IL中,我会得到:

.method private hidebysig static void  Test() cil managed
{
  // Code size       16 (0x10)
  .maxstack  1
  .locals init ([0] int32 v)
  IL_0000:  nop
  IL_0001:  ldc.i4.5
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  box        [mscorlib]System.Int32
  IL_0009:  call       void ConsoleApplication6.Session::PrintDynamic(object)
  IL_000e:  nop
  IL_000f:  ret
} 
您可以看到,尽管
Test
的参数被声明为
dynamic
,但整数仍被装箱

编辑

针对你在时间上的差异提出的问题,考虑以下方法:

    static void Print(object p)
    {
        string.Format("{0}", p);
    }

    static void PrintDynamic(dynamic p)
    {
        string.Format("{0}", p);
    }
第一个的IL如下所示:

.method private hidebysig static void  Print(object p) cil managed
{
  // Code size       14 (0xe)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "{0}"
  IL_0006:  ldarg.0
  IL_0007:  call       string [mscorlib]System.String::Format(string,
                                                              object)
  IL_000c:  pop
  IL_000d:  ret
} // end of method TestClass::Print
第二项:

.method private hidebysig static void  PrintDynamic(object p) cil managed
{
  .param [1]
  .custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       123 (0x7b)
  .maxstack  8
  .locals init ([0] class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[] CS$0$0000)
  IL_0000:  nop
  IL_0001:  ldsfld     class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`4<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,string,object>> ConsoleApplication6.TestClass/'<PrintDynamic>o__SiteContainer0'::'<>p__Site1'
  IL_0006:  brtrue.s   IL_0055
  IL_0008:  ldc.i4     0x100
  IL_000d:  ldstr      "Format"
  IL_0012:  ldnull
  IL_0013:  ldtoken    ConsoleApplication6.TestClass
  IL_0018:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
  IL_001d:  ldc.i4.3
  IL_001e:  newarr     [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo
  IL_0023:  stloc.0
  IL_0024:  ldloc.0
  IL_0025:  ldc.i4.0
  IL_0026:  ldc.i4.s   33
  IL_0028:  ldnull
  IL_0029:  call       class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
                                                                                                                                                                             string)
  IL_002e:  stelem.ref
  IL_002f:  ldloc.0
  IL_0030:  ldc.i4.1
  IL_0031:  ldc.i4.3
  IL_0032:  ldnull
  IL_0033:  call       class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
                                                                                                                                                                             string)
  IL_0038:  stelem.ref
  IL_0039:  ldloc.0
  IL_003a:  ldc.i4.2
  IL_003b:  ldc.i4.0
  IL_003c:  ldnull
  IL_003d:  call       class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
                                                                                                                                                                             string)
  IL_0042:  stelem.ref
  IL_0043:  ldloc.0
  IL_0044:  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_0049:  call       class [System.Core]System.Runtime.CompilerServices.CallSite`1<!0> class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`4<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,string,object>>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder)
  IL_004e:  stsfld     class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`4<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,string,object>> ConsoleApplication6.TestClass/'<PrintDynamic>o__SiteContainer0'::'<>p__Site1'
  IL_0053:  br.s       IL_0055
  IL_0055:  ldsfld     class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`4<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,string,object>> ConsoleApplication6.TestClass/'<PrintDynamic>o__SiteContainer0'::'<>p__Site1'
  IL_005a:  ldfld      !0 class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`4<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,string,object>>::Target
  IL_005f:  ldsfld     class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`4<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,string,object>> ConsoleApplication6.TestClass/'<PrintDynamic>o__SiteContainer0'::'<>p__Site1'
  IL_0064:  ldtoken    [mscorlib]System.String
  IL_0069:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
  IL_006e:  ldstr      "{0}"
  IL_0073:  ldarg.0
  IL_0074:  callvirt   instance void class [mscorlib]System.Action`4<class [System.Core]System.Runtime.CompilerServices.CallSite,class [mscorlib]System.Type,string,object>::Invoke(!0,
                                                                                                                                                                                    !1,
                                                                                                                                                                                    !2,
                                                                                                                                                                                    !3)
  IL_0079:  nop
  IL_007a:  ret
} // end of method TestClass::PrintDynamic
.method private隐藏静态void PrintDynamic(对象p)cil管理
{
.param[1]
.custom实例void[System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor()=(01 00)
//代码大小123(0x7b)
.maxstack 8
.locals init([0]类[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[]CS$0$0000)
IL_0000:没有
IL_0001:ldsfld类[System.Core]System.Runtime.CompilerServices.CallSite`1 ConsoleApplication6.TestClass/'o_uSiteContainer0'::'p_uSite1'
IL_0006:brtrue.s IL_0055
IL_0008:ldc.i4 0x100
IL_000d:ldstr“格式”
IL_0012:ldnull
IL_0013:ldtoken控制台应用程序6.TestClass
IL_0018:调用类[mscorlib]System.Type[mscorlib]System.Type::GetTypeFromHandle(valuetype[mscorlib]System.RuntimeTypeHandle)
IL_001d:ldc.i4.3
IL_001e:newarr[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo
IL_0023:stloc.0
IL_0024:ldloc.0
IL_0025:ldc.i4.0
IL_0026:ldc.i4.s 33
IL_0028:ldnull
IL_0029:调用类[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(值类型[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
(字符串)
IL_002e:stelem.ref
IL_002f:ldloc.0
IL_0030:ldc.i4.1
IL_0031:ldc.i4.3
IL_0032:ldnull
IL_0033:调用类[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(值类型[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
(字符串)
IL_0038:stelem.ref
IL_0039:ldloc.0
IL_003a:ldc.i4.2
IL_003b:ldc.i4.0
IL_003c:ldnull
IL_003d:调用类[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(值类型[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,
(字符串)
IL_0042:stelem.ref
IL_0043:ldloc.0
IL_0044:调用类[System.Core]System.Runtime.CompilerServices.CallSiteBinder[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::InvokeMember(valuetype[Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,
一串
类[mscorlib]System.Collections.Generic.IEnumerable`1,
类[mscorlib]System.Type,
类[mscorlib]System.Collections.Generic.IEnumerable`1)
IL_0049:调用类[System.Core]System.Runtime.CompilerServices.CallSite`1类[System.Core]System.Runtime.CompilerServices.CallSite`1::Create(类[System.Core]System.Runtime.CompilerServices.CallSiteBinder)
IL_004e:stsfld类[System.Core]System.Runtime.CompilerServices.CallSite`1 ConsoleApplication6.TestClass/'o_uSiteContainer0':'p_uSite1'
ILU 0053:br.s ILU 0055
IL_0055:ldsfld类[System.Core]System.Runtime.CompilerServices.CallSite`1 ConsoleApplication6.TestClass/'o_uSiteContainer0'::'p_uSite1'
IL_005a:ldfld!0类[System.Core]System.Runtime.CompilerServices.CallSite`1::Target
IL_005f:ldsfld类[System.Core]System.Runtime.CompilerServices.CallSite`1 ConsoleApplication6.TestClass/'o_uSiteContainer0':'p_uSite1'
IL_0064:ldtoken[mscorlib]System.String
IL_0069:调用类[mscorlib]System.Type[mscorlib]System.Type::GetTypeFromHandle(valuetype[mscorlib]System.RuntimeTypeHandle)
IL_006e:ldstr“{0}”
IL_0073:ldarg.0
IL_0074:callvirt实例无效类[mscorlib]系统。操作'4::调用(!0,