在拳擊方面,它沒有什麼區別。看看下面的代碼:
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
這有些方法可以解釋爲什麼最初使用dynamic
需要更長的時間。我懷疑有一些緩存機制正在進行,這意味着第一次之後你不會獲得性能。
a)您是否親自測量過? b)你是預先優化(你不應該)還是隻是好奇? c)從不(很少)使用動態關鍵字 - 有龍。 – Gusdor
d)給一個有意義的標題。 – 2013-10-18 10:56:39
是的,我已經證實,但對於拳擊/ UnBoxing它需要0/1毫秒,但對於動態,它需要第一次大約39毫秒和下一個連續2毫秒.. :( – dinesh