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,