C#4.0初探:dynamic 关键字
2009-05-29 08:31:21 来源:WEB开发网目前dynamic类型对属性调用是不可用的,但我们知道,属性生成IL时,对属性的读或写会生成对应的在属性名前加上get_或set_前缀生成相应的方法,尝试调用两个方法来访问属性:
dynamic myInfo = new Me();
myInfo.set_Blog("http://www.xianfen.net/");
string result = myInfo.get_Blog();
会抛出异常,提示找不到get/set_Blog方法。这点比较遗憾,同样,对有参属性的访问也是不行的。
反射还可以访问私有方法字段以及其它类型成员及取得类型及类型成员的信息等。
dynamic类型的效率
效率问题应该是大家很关心的,我的感觉:不要对动态语言有很高的效率抱有太大的希望,但另一方面,算法的设计对效率的影响非常大,功能与性能经常存在一个平衡点。
要分析其效率,就要看看编译后内部都干了些啥,方法是写些简单的代码,查看IL。
代码:
using System;
namespace Xianfen.Net.TestDynamic
{
class Program
{
static void Main()
{
dynamic d = "str";
d.ToString();
}
}
}
对应的IL代码:
.class private auto ansi beforefieldinit Program
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: call instance void [mscorlib]System.Object::.ctor()
L_0006: ret
}
.method private hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 9
.locals init (
[0] object d,
[1] class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[] CS$0$0000)
L_0000: ldstr "str"
L_0005: stloc.0
L_0006: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`2<class [System.Core]System.Runtime.CompilerServices.CallSite, object>> Xianfen.Net.TestDynamic.Program/<Main>o__SiteContainer0::<>p__Site1
L_000b: brtrue.s L_003f
L_000d: ldc.i4.0
L_000e: ldstr "ToString"
L_0013: ldtoken Xianfen.Net.TestDynamic.Program
L_0018: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
L_001d: ldnull
L_001e: ldc.i4.1
L_001f: newarr [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo
L_0024: stloc.1
L_0025: ldloc.1
L_0026: ldc.i4.0
L_0027: ldc.i4.0
L_0028: ldnull
L_0029: newobj instance void [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::.ctor(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)
L_002e: stelem.ref
L_002f: ldloc.1
L_0030: newobj instance void [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder::.ctor(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpCallFlags, string, class [mscorlib]System.Type, class [mscorlib]System.Collections.Generic.IEnumerable`1<class [mscorlib]System.Type>, class [mscorlib]System.Collections.Generic.IEnumerable`1<class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)
L_0035: call class [System.Core]System.Runtime.CompilerServices.CallSite`1<!0> [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`2<class [System.Core]System.Runtime.CompilerServices.CallSite, object>>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder)
L_003a: stsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`2<class [System.Core]System.Runtime.CompilerServices.CallSite, object>> Xianfen.Net.TestDynamic.Program/<Main>o__SiteContainer0::<>p__Site1
L_003f: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`2<class [System.Core]System.Runtime.CompilerServices.CallSite, object>> Xianfen.Net.TestDynamic.Program/<Main>o__SiteContainer0::<>p__Site1
L_0044: ldfld !0 [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`2<class [System.Core]System.Runtime.CompilerServices.CallSite, object>>::Target
L_0049: ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`2<class [System.Core]System.Runtime.CompilerServices.CallSite, object>> Xianfen.Net.TestDynamic.Program/<Main>o__SiteContainer0::<>p__Site1
L_004e: ldloc.0
L_004f: callvirt instance void [mscorlib]System.Action`2<class [System.Core]System.Runtime.CompilerServices.CallSite, object>::Invoke(!0, !1)
L_0054: ret
}
.class abstract auto ansi sealed nested private beforefieldinit <Main>o__SiteContainer0
extends [mscorlib]System.Object
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
.field public static class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Action`2<class [System.Core]System.Runtime.CompilerServices.CallSite, object>> <>p__Site1
}
}
更多精彩
赞助商链接