我觉得C#编译器编译为IL语言时,遵循下面一个规律
*
* 对于非虚方法编译为IL时候,
*编译为,找到离编译时所能知道的对象类型最近的并且定义过这个函数的class,定义为 <离编译时所能知道的对象类型最近的并且定义过这个函数的class>.<Function>
*如果使用this调用,使用call; 如果使用instance调用,使用callvirt (因为instance可能会抛nullreferenceexception,而this永远不会)
* 运行时,如果是call,直接调用这个<找到离编译时所能知道的对象类型最近的并且定义过这个函数的class>.<Function>
* 但如果是callvirt,会到虚函数表中查找(其实多此一举),什么也不会有,然后仍然调用<找到离编译时所能知道的对象类型最近的并且定义过这个函数的class>.<Function>
*
* 对虚方法编译为IL时候,
*编译为,找到离编译时所能知道的对象类型最远的并且定义过这个函数的class,定义为 <离编译时所能知道的对象类型最远的并且定义过这个函数的class>.<Function>
* 一般使用callvirt,除非base.虚方法(), 值类型.虚方法(), Sealed Instance.虚方法()
*然后,在运行时,知道对象的实际类型,再根据虚函数表,调用离实际类型最近的,并且override这个函数的class,然后调用这个override的Function
*对于上述几点,注意关键字new的阻断作用
snippet1:
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
3
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
5
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
13
![ExpandedBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
14
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
15
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
16
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
17
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
19
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
20
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
21
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
22
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
24
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
26
![ExpandedBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
27
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
28
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
29
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
30
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
31
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
32
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
33
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
34
![ExpandedBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
那么结果是什么呢?
result1:
Non Virtual Base 000
VirtualWork DerivedLayer1 111
结果正如我们料想的那样,很简单,
![emteeth.gif](https://www.cnblogs.com/CuteSoft_Client/CuteEditor/images/emteeth.gif)
我们看看Main函数的IL:
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![ExpandedBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
对于
Base b = new DerivedLayer1();
b.DoNoVirtualWork(); => callvirt instance void ConsoleApplication1.Base::DoNoVirtualWork()
//上面这句,因为编译器知道b的类型是Base,而是非虚函数,编译器寻找离Base最近而且定义过DoNoVirtualWork()的class,就是Base本身, 所以要调用ConsoleApplication1.Base::DoNoVirtualWork() 即:<离编译时所能知道的对象类型最近的并且定义过这个函数的class>.<Function>
b.DoVirtualWork(); => callvirt instance void ConsoleApplication1.Base::DoVirtualWork()
//上面这句,因为编译器知道b的类型是Base,它是一个虚函数,所以要寻找最早定义过DoVirtualWork()的class,就是Base本身,所以是 ConsoleApplication1.Base::DoVirtualWork(),即<离编译时所能知道的对象类型最远的并且定义过这个函数的class>.<Function>
下面代码换成snippet2
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
3
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
5
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
14
![ExpandedBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
15
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
16
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
17
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
18
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
20
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
22
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
24
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
25
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
26
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
27
![ExpandedBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
28
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
29
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
30
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
31
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
32
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
33
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
34
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
35
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
36
![ExpandedBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
37
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
注意DerivedLayer1没有override Base的DoVirtualWork(), 但是却用new 重新定义了DoNoVirtualWork()
这时候的结果会是什么呢
我们继续使用上面的规律来产生IL
DerivedLayer1 d1 = new DerivedLayer1();
d1.DoNoVirtualWork();
//对于上面这句语句,编译器所能知道的类型是DerivedLayer1 ,它是非虚拟函数,而离DerivedLayer1 最近,且定义过DoNoVirtualWork()的class就是它自己,所以根据<找到离编译时所能知道的对象类型最近的并且定义过这个函数的class>>.<Function>, 应该是: callvirt DerivedLayer1::DoNoVirtualWork(); 我们用ildasm看一下,果然如此:callvirt instance void ConsoleApplication1.DerivedLayer1::DoNoVirtualWork(),所以输出“Non Virtual DerivedLayer1 111”;
而d1.DoVirtualWork();
//对于上面这一句,<离编译时所能知道的对象类型最远的并且定义过这个函数的class>.<Function>,编译器这是所能知道d1的类型是DerivedLayer1 ,离DerivedLayer1 最远并且定义过DoVirtualWork()的class是Base,所以IL应该是callvirt Base::DoVirtualWork(),使用ildasm查看
callvirt instance void ConsoleApplication1.Base::DoVirtualWork() ,也是如此,使用callvirt在运行时,需要在v-table中产看离当前实际类型(DerivedLayer1),最近并且定义过DoVirtualWork的class是Base,所以输出“VirtualWork Base 000”;
所以结果是
Non Virtual DerivedLayer1 111
VirtualWork Base 000
下面复杂一点,需要考虑new的阻断情况,但仍然符合这个规律。
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
3
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
5
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
18
![ExpandedBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
19
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
20
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
21
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
22
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
24
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
26
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
28
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
29
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
30
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
31
![ExpandedBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
32
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
33
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
34
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
35
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
36
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
37
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
38
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
39
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
40
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
41
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
42
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
43
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
44
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
45
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
46
![ExpandedBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
47
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
48
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
49
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
50
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
51
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
52
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
53
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
54
![ExpandedSubBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
55
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
56
![ExpandedBlockEnd.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
这次的结果会是什么呢?注意"new",也许不是那么容易
让我们来看一下产生的IL语句
Base b = new DerivedLayer2();
b.DoNoVirtualWork(); => callvirt instance void ConsoleApplication1.Base::DoNoVirtualWork()
b.DoVirtualWork(); => callvirt instance void ConsoleApplication1.Base::DoVirtualWork()
Console.WriteLine("********");
DerivedLayer1 d1 = new DerivedLayer2();
d1.DoNoVirtualWork();=>callvirt instance void ConsoleApplication1.DerivedLayer1::DoNoVirtualWork()
d1.DoVirtualWork(); =>callvirt instance void ConsoleApplication1.DerivedLayer1::DoVirtualWork()
结果是:
Non Virtual Base 000
VirtualWork Base 000
********
Non Virtual DerivedLayer1 111
VirtualWork DerivedLayer2 222
另外,什么时候会编译成callvirt,什么时候编译成call,可以看 .net Framework 程序设计,
对虚方法编译为IL时候,一般使用callvirt,除非base.虚方法(), 值类型.虚方法() , Sealed Instance.虚方法()
比如值类型override了ToString(),调用的时候会使用call,不会被装箱。
对于非虚方法,可能会抛nullreferenceexception,会使用call