c#4.0新特性之一: Dynamic Lookup (1)
2008-10-30 00:19
501 查看
废话不多说,直接开始。先看程序:
Code
1
class Program
2
{
3
static void Main(string[] args)
4
{
5
dynamic foo1 = new Foo();
6
foo1.Do1();
7
foo1.Do2();
8
foo1.KissFanweixiao();
9
}
10
}
11
12
public class Foo
13
{
14
public void Do1()
{ Console.WriteLine("fanweixiao calls do1"); }
15
public void Do2()
{ Console.WriteLine("fanweixiao calls do2"); }
16
}
这段代码在vs2010中可以编译通过。但是在运行的时候会报错。这是必然,KissFanweixiao()这个方法无中生有嘛。
这里注意到这是个RuntimeBinderException,而内容是不能找到KissFanweixiao的符号。
dynamic这个关键字看起来跟3.0增加的var很像,但是从IL的角度上来看,就是天壤之别了,毕竟var是编译时就能确定的东西,而dynamic追求的就是在运行时再决定究竟是个什么东西。我们还是先注释掉foo1.KissFanweixiao();这一句,使程序可以正常运行,然后看ILDASM的结果:
多出一个<Main>o__SiteContainer0类,这个类下的<>p__Site1...和<>p__Site2...对应着Do1()和Do2()两个方法的Invoke。再细看此时的Main函数:
Code
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 139 (0x8b)
.maxstack 7
.locals init ([0] object foo1)
IL_0000: newobj instance void LearnCSharp4.Foo::.ctor()
IL_0005: stloc.0
IL_0006: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
IL_000b: brtrue.s IL_0033
IL_000d: call class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder::GetInstance()
IL_0012: ldc.i4.0
IL_0013: ldc.i4.0
IL_0014: ldstr "Do1"
IL_0019: ldtoken [mscorlib]System.Object
IL_001e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0023: ldnull
IL_0024: newobj instance void [System.Core]Microsoft.CSharp.RuntimeBinder.CSharpCallPayload::.ctor(class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder,
bool,
bool,
string,
class [mscorlib]System.Type,
class [mscorlib]System.Type[])
IL_0029: call class [System.Core]System.Scripting.Actions.CallSite`1<!0> class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Create(class [System.Core]System.Scripting.Actions.CallSiteBinder)
IL_002e: stsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
IL_0033: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
IL_0038: ldfld !0 class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Target
IL_003d: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
IL_0042: ldloc.0
IL_0043: callvirt instance void class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>::Invoke(!0,
!1)
IL_0048: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
IL_004d: brtrue.s IL_0075
IL_004f: call class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder::GetInstance()
IL_0054: ldc.i4.0
IL_0055: ldc.i4.0
IL_0056: ldstr "Do2"
IL_005b: ldtoken [mscorlib]System.Object
IL_0060: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0065: ldnull
IL_0066: newobj instance void [System.Core]Microsoft.CSharp.RuntimeBinder.CSharpCallPayload::.ctor(class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder,
bool,
bool,
string,
class [mscorlib]System.Type,
class [mscorlib]System.Type[])
IL_006b: call class [System.Core]System.Scripting.Actions.CallSite`1<!0> class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Create(class [System.Core]System.Scripting.Actions.CallSiteBinder)
IL_0070: stsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
IL_0075: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
IL_007a: ldfld !0 class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Target
IL_007f: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
IL_0084: ldloc.0
IL_0085: callvirt instance void class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>::Invoke(!0,
!1)
IL_008a: ret
} // end of method Program::Main
如果是var或Foo的话直接这样就完事了:
Code
1 IL_0000: newobj instance void LearnCSharp4.Foo::.ctor()
2 IL_0005: stloc.0
3 IL_0006: ldloc.0
4 IL_0007: callvirt instance void LearnCSharp4.Foo::Do1()
5 IL_000c: ldloc.0
6 IL_000d: callvirt instance void LearnCSharp4.Foo::Do2()
7 IL_0012: ret
OK,看出不同来了。然后取消掉对foo.KissFanweixiao();的注释,再编译,再用ILDASM看,Do1()和KissFanWeixiao()的地位应该是一样的——因为dynamic与编译时无关嘛(好像是废话...但是这点很重要)。我们再看一眼有三个方法后的MSIL:
Code
1
.method private hidebysig static void Main(string[] args) cil managed
2
{
3
.entrypoint
4
// Code size 205 (0xcd)
5
.maxstack 7
6
.locals init ([0] object foo1)
7
IL_0000: newobj instance void LearnCSharp4.Foo::.ctor()
8
IL_0005: stloc.0
9
IL_0006: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
10
IL_000b: brtrue.s IL_0033
11
IL_000d: call class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder::GetInstance()
12
IL_0012: ldc.i4.0
13
IL_0013: ldc.i4.0
14
IL_0014: ldstr "Do1"
15
IL_0019: ldtoken [mscorlib]System.Object
16
IL_001e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
17
IL_0023: ldnull
18
IL_0024: newobj instance void [System.Core]Microsoft.CSharp.RuntimeBinder.CSharpCallPayload::.ctor(class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder,
19
bool,
20
bool,
21
string,
22
class [mscorlib]System.Type,
23
class [mscorlib]System.Type[])
24
IL_0029: call class [System.Core]System.Scripting.Actions.CallSite`1<!0> class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Create(class [System.Core]System.Scripting.Actions.CallSiteBinder)
25
IL_002e: stsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
26
IL_0033: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
27
IL_0038: ldfld !0 class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Target
28
IL_003d: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
29
IL_0042: ldloc.0
30
IL_0043: callvirt instance void class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>::Invoke(!0,
31
!1)
32
IL_0048: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
33
IL_004d: brtrue.s IL_0075
34
IL_004f: call class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder::GetInstance()
35
IL_0054: ldc.i4.0
36
IL_0055: ldc.i4.0
37
IL_0056: ldstr "Do2"
38
IL_005b: ldtoken [mscorlib]System.Object
39
IL_0060: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
40
IL_0065: ldnull
41
IL_0066: newobj instance void [System.Core]Microsoft.CSharp.RuntimeBinder.CSharpCallPayload::.ctor(class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder,
42
bool,
43
bool,
44
string,
45
class [mscorlib]System.Type,
46
class [mscorlib]System.Type[])
47
IL_006b: call class [System.Core]System.Scripting.Actions.CallSite`1<!0> class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Create(class [System.Core]System.Scripting.Actions.CallSiteBinder)
48
IL_0070: stsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
49
IL_0075: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
50
IL_007a: ldfld !0 class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Target
51
IL_007f: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
52
IL_0084: ldloc.0
53
IL_0085: callvirt instance void class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>::Invoke(!0,
54
!1)
55
IL_008a: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site3'
56
IL_008f: brtrue.s IL_00b7
57
IL_0091: call class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder::GetInstance()
58
IL_0096: ldc.i4.0
59
IL_0097: ldc.i4.0
60
IL_0098: ldstr "KissFanweixiao"
61
IL_009d: ldtoken [mscorlib]System.Object
62
IL_00a2: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
63
IL_00a7: ldnull
64
IL_00a8: newobj instance void [System.Core]Microsoft.CSharp.RuntimeBinder.CSharpCallPayload::.ctor(class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder,
65
bool,
66
bool,
67
string,
68
class [mscorlib]System.Type,
69
class [mscorlib]System.Type[])
70
IL_00ad: call class [System.Core]System.Scripting.Actions.CallSite`1<!0> class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Create(class [System.Core]System.Scripting.Actions.CallSiteBinder)
71
IL_00b2: stsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site3'
72
IL_00b7: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site3'
73
IL_00bc: ldfld !0 class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Target
74
IL_00c1: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site3'
75
IL_00c6: ldloc.0
76
IL_00c7: callvirt instance void class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>::Invoke(!0,
77
!1)
78
IL_00cc: ret
79
} // end of method Program::Main
如果不喜欢看MSIL的话可以这样看:
Code
1
private static void Main(string[] args)
2
{
3
object foo1 = new Foo();
4
if (<Main>o__SiteContainer0.<>p__Site1 == null)
5
{
6
<Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, object>>.Create(new CSharpCallPayload(Microsoft.CSharp.RuntimeBinder.RuntimeBinder.GetInstance(), false, false, "Do1", typeof(object), null));
7
}
8
<Main>o__SiteContainer0.<>p__Site1.Target(<Main>o__SiteContainer0.<>p__Site1, foo1);
9
if (<Main>o__SiteContainer0.<>p__Site2 == null)
10
{
11
<Main>o__SiteContainer0.<>p__Site2 = CallSite<Action<CallSite, object>>.Create(new CSharpCallPayload(Microsoft.CSharp.RuntimeBinder.RuntimeBinder.GetInstance(), false, false, "Do2", typeof(object), null));
12
}
13
<Main>o__SiteContainer0.<>p__Site2.Target(<Main>o__SiteContainer0.<>p__Site2, foo1);
14
if (<Main>o__SiteContainer0.<>p__Site3 == null)
15
{
16
<Main>o__SiteContainer0.<>p__Site3 = CallSite<Action<CallSite, object>>.Create(new CSharpCallPayload(Microsoft.CSharp.RuntimeBinder.RuntimeBinder.GetInstance(), false, false, "KissFanweixiao", typeof(object), null));
17
}
18
<Main>o__SiteContainer0.<>p__Site3.Target(<Main>o__SiteContainer0.<>p__Site3, foo1);
19
}
本文旨在为不方便下载和使用vs2010虚拟机朋友帮个忙.
Code
1
class Program
2
{
3
static void Main(string[] args)
4
{
5
dynamic foo1 = new Foo();
6
foo1.Do1();
7
foo1.Do2();
8
foo1.KissFanweixiao();
9
}
10
}
11
12
public class Foo
13
{
14
public void Do1()
{ Console.WriteLine("fanweixiao calls do1"); }
15
public void Do2()
{ Console.WriteLine("fanweixiao calls do2"); }
16
}
这段代码在vs2010中可以编译通过。但是在运行的时候会报错。这是必然,KissFanweixiao()这个方法无中生有嘛。
这里注意到这是个RuntimeBinderException,而内容是不能找到KissFanweixiao的符号。
dynamic这个关键字看起来跟3.0增加的var很像,但是从IL的角度上来看,就是天壤之别了,毕竟var是编译时就能确定的东西,而dynamic追求的就是在运行时再决定究竟是个什么东西。我们还是先注释掉foo1.KissFanweixiao();这一句,使程序可以正常运行,然后看ILDASM的结果:
多出一个<Main>o__SiteContainer0类,这个类下的<>p__Site1...和<>p__Site2...对应着Do1()和Do2()两个方法的Invoke。再细看此时的Main函数:
Code
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 139 (0x8b)
.maxstack 7
.locals init ([0] object foo1)
IL_0000: newobj instance void LearnCSharp4.Foo::.ctor()
IL_0005: stloc.0
IL_0006: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
IL_000b: brtrue.s IL_0033
IL_000d: call class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder::GetInstance()
IL_0012: ldc.i4.0
IL_0013: ldc.i4.0
IL_0014: ldstr "Do1"
IL_0019: ldtoken [mscorlib]System.Object
IL_001e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0023: ldnull
IL_0024: newobj instance void [System.Core]Microsoft.CSharp.RuntimeBinder.CSharpCallPayload::.ctor(class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder,
bool,
bool,
string,
class [mscorlib]System.Type,
class [mscorlib]System.Type[])
IL_0029: call class [System.Core]System.Scripting.Actions.CallSite`1<!0> class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Create(class [System.Core]System.Scripting.Actions.CallSiteBinder)
IL_002e: stsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
IL_0033: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
IL_0038: ldfld !0 class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Target
IL_003d: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
IL_0042: ldloc.0
IL_0043: callvirt instance void class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>::Invoke(!0,
!1)
IL_0048: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
IL_004d: brtrue.s IL_0075
IL_004f: call class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder::GetInstance()
IL_0054: ldc.i4.0
IL_0055: ldc.i4.0
IL_0056: ldstr "Do2"
IL_005b: ldtoken [mscorlib]System.Object
IL_0060: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0065: ldnull
IL_0066: newobj instance void [System.Core]Microsoft.CSharp.RuntimeBinder.CSharpCallPayload::.ctor(class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder,
bool,
bool,
string,
class [mscorlib]System.Type,
class [mscorlib]System.Type[])
IL_006b: call class [System.Core]System.Scripting.Actions.CallSite`1<!0> class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Create(class [System.Core]System.Scripting.Actions.CallSiteBinder)
IL_0070: stsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
IL_0075: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
IL_007a: ldfld !0 class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Target
IL_007f: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
IL_0084: ldloc.0
IL_0085: callvirt instance void class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>::Invoke(!0,
!1)
IL_008a: ret
} // end of method Program::Main
如果是var或Foo的话直接这样就完事了:
Code
1 IL_0000: newobj instance void LearnCSharp4.Foo::.ctor()
2 IL_0005: stloc.0
3 IL_0006: ldloc.0
4 IL_0007: callvirt instance void LearnCSharp4.Foo::Do1()
5 IL_000c: ldloc.0
6 IL_000d: callvirt instance void LearnCSharp4.Foo::Do2()
7 IL_0012: ret
OK,看出不同来了。然后取消掉对foo.KissFanweixiao();的注释,再编译,再用ILDASM看,Do1()和KissFanWeixiao()的地位应该是一样的——因为dynamic与编译时无关嘛(好像是废话...但是这点很重要)。我们再看一眼有三个方法后的MSIL:
Code
1
.method private hidebysig static void Main(string[] args) cil managed
2
{
3
.entrypoint
4
// Code size 205 (0xcd)
5
.maxstack 7
6
.locals init ([0] object foo1)
7
IL_0000: newobj instance void LearnCSharp4.Foo::.ctor()
8
IL_0005: stloc.0
9
IL_0006: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
10
IL_000b: brtrue.s IL_0033
11
IL_000d: call class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder::GetInstance()
12
IL_0012: ldc.i4.0
13
IL_0013: ldc.i4.0
14
IL_0014: ldstr "Do1"
15
IL_0019: ldtoken [mscorlib]System.Object
16
IL_001e: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
17
IL_0023: ldnull
18
IL_0024: newobj instance void [System.Core]Microsoft.CSharp.RuntimeBinder.CSharpCallPayload::.ctor(class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder,
19
bool,
20
bool,
21
string,
22
class [mscorlib]System.Type,
23
class [mscorlib]System.Type[])
24
IL_0029: call class [System.Core]System.Scripting.Actions.CallSite`1<!0> class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Create(class [System.Core]System.Scripting.Actions.CallSiteBinder)
25
IL_002e: stsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
26
IL_0033: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
27
IL_0038: ldfld !0 class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Target
28
IL_003d: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site1'
29
IL_0042: ldloc.0
30
IL_0043: callvirt instance void class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>::Invoke(!0,
31
!1)
32
IL_0048: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
33
IL_004d: brtrue.s IL_0075
34
IL_004f: call class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder::GetInstance()
35
IL_0054: ldc.i4.0
36
IL_0055: ldc.i4.0
37
IL_0056: ldstr "Do2"
38
IL_005b: ldtoken [mscorlib]System.Object
39
IL_0060: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
40
IL_0065: ldnull
41
IL_0066: newobj instance void [System.Core]Microsoft.CSharp.RuntimeBinder.CSharpCallPayload::.ctor(class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder,
42
bool,
43
bool,
44
string,
45
class [mscorlib]System.Type,
46
class [mscorlib]System.Type[])
47
IL_006b: call class [System.Core]System.Scripting.Actions.CallSite`1<!0> class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Create(class [System.Core]System.Scripting.Actions.CallSiteBinder)
48
IL_0070: stsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
49
IL_0075: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
50
IL_007a: ldfld !0 class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Target
51
IL_007f: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site2'
52
IL_0084: ldloc.0
53
IL_0085: callvirt instance void class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>::Invoke(!0,
54
!1)
55
IL_008a: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site3'
56
IL_008f: brtrue.s IL_00b7
57
IL_0091: call class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder::GetInstance()
58
IL_0096: ldc.i4.0
59
IL_0097: ldc.i4.0
60
IL_0098: ldstr "KissFanweixiao"
61
IL_009d: ldtoken [mscorlib]System.Object
62
IL_00a2: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
63
IL_00a7: ldnull
64
IL_00a8: newobj instance void [System.Core]Microsoft.CSharp.RuntimeBinder.CSharpCallPayload::.ctor(class [System.Core]Microsoft.CSharp.RuntimeBinder.RuntimeBinder,
65
bool,
66
bool,
67
string,
68
class [mscorlib]System.Type,
69
class [mscorlib]System.Type[])
70
IL_00ad: call class [System.Core]System.Scripting.Actions.CallSite`1<!0> class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Create(class [System.Core]System.Scripting.Actions.CallSiteBinder)
71
IL_00b2: stsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site3'
72
IL_00b7: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site3'
73
IL_00bc: ldfld !0 class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>>::Target
74
IL_00c1: ldsfld class [System.Core]System.Scripting.Actions.CallSite`1<class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>> LearnCSharp4.Program/'<Main>o__SiteContainer0'::'<>p__Site3'
75
IL_00c6: ldloc.0
76
IL_00c7: callvirt instance void class [System.Core]System.Action`2<class [System.Core]System.Scripting.Actions.CallSite,object>::Invoke(!0,
77
!1)
78
IL_00cc: ret
79
} // end of method Program::Main
如果不喜欢看MSIL的话可以这样看:
Code
1
private static void Main(string[] args)
2
{
3
object foo1 = new Foo();
4
if (<Main>o__SiteContainer0.<>p__Site1 == null)
5
{
6
<Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, object>>.Create(new CSharpCallPayload(Microsoft.CSharp.RuntimeBinder.RuntimeBinder.GetInstance(), false, false, "Do1", typeof(object), null));
7
}
8
<Main>o__SiteContainer0.<>p__Site1.Target(<Main>o__SiteContainer0.<>p__Site1, foo1);
9
if (<Main>o__SiteContainer0.<>p__Site2 == null)
10
{
11
<Main>o__SiteContainer0.<>p__Site2 = CallSite<Action<CallSite, object>>.Create(new CSharpCallPayload(Microsoft.CSharp.RuntimeBinder.RuntimeBinder.GetInstance(), false, false, "Do2", typeof(object), null));
12
}
13
<Main>o__SiteContainer0.<>p__Site2.Target(<Main>o__SiteContainer0.<>p__Site2, foo1);
14
if (<Main>o__SiteContainer0.<>p__Site3 == null)
15
{
16
<Main>o__SiteContainer0.<>p__Site3 = CallSite<Action<CallSite, object>>.Create(new CSharpCallPayload(Microsoft.CSharp.RuntimeBinder.RuntimeBinder.GetInstance(), false, false, "KissFanweixiao", typeof(object), null));
17
}
18
<Main>o__SiteContainer0.<>p__Site3.Target(<Main>o__SiteContainer0.<>p__Site3, foo1);
19
}
本文旨在为不方便下载和使用vs2010虚拟机朋友帮个忙.
相关文章推荐
- c#4.0新特性之一: Dynamic Lookup (1)
- c#4.0新特性之一: Dynamic Lookup (2)
- C#4.0新特性(1):Dynamic Lookup 动态查找
- c#4.0新特性之一: Dynamic Lookup (2)
- C#4.0新特性:可选参数,命名参数,Dynamic
- C#4.0新特性:可选参数,命名参数,Dynamic
- C#4.0新特性:可选参数,命名参数,Dynamic
- C#4.0新特性:可选参数,命名参数,Dynamic
- C#4.0新特性之二:Named and Optional Parameters
- C#4.0新特性之二:Named and Optional Parameters (2) 剖析篇
- AS3面向对象的特性,其中包括了dynamic解释
- C#4.0新特性之元组Tuple
- C#4.0新特性
- .net 4.0 中的特性总结(一):dynamic
- ASP.NET 3.5 Extensions新特性:ASP.NET Dynamic Data 体验(上)
- C#4.0和VS2010新特性(一)
- .Net 4.0新特性之Dynamic 动态类型(转载)
- C#4.0的dynamic和var及object关键字辨析
- C#一些新特性Object,var,dynamic,asynchronous
- 在Dynamic Data Framework下实现Lookup字段下拉列表模板