Refresher of IL explains "this pointer" in C#

这篇文章里,用il语言解释一下static方法和non-static方法在调用的时候,堆栈顶部传递参数的不同形式。
首先看一段代码:
 class TestClass
    {
        public static readonly int i = 10;
        static void Main(string[] args)
        {           
            TestClass testClass = new TestClass();
            TestStatic();
            testClass.NonStatic();
        }

        public static void TestStatic()
        {
        }

        public void NonStatic()
        {
        }
    }

反编译以后得到:
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       21 (0x15)
  .maxstack  1
  .locals init ([0] class TestConcoleApp.TestClass testClass)
  IL_0000:  nop
  IL_0001:  newobj     instance void TestConcoleApp.TestClass::.ctor()
  IL_0006:  stloc.0
  IL_0007:  call       void TestConcoleApp.TestClass::TestStatic()
  IL_000c:  nop
  IL_000d:  ldloc.0
  IL_000e:  callvirt   instance void TestConcoleApp.TestClass::NonStatic()
  IL_0013:  nop
  IL_0014:  ret
} // end of method TestClass::Main

首先,关于this pointer,可以参考ibm的文档:
http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/cplr035.htm

注意蓝色的这一行。这一行说明了一个问题,在使用static方法和non-static方法的时候,static方法并不pass this pointer到stack中去。而non-static方法确需要传递一个instance的reference到stack中去。

因为,在
  IL_0001:  newobj     instance void TestConcoleApp.TestClass::.ctor()
  IL_0006:  stloc.0

指令中,存储了新实例化的一个变量到loc.0中去了,然后在调用static方法的时候,堆栈的顶部是没有obj的reference的。而调用non-static方法的时候,需要传递一个obj的reference到堆栈的顶部去。

如果大家想继续深入了解为什么static方法不需要传递一个obj的reference,可以参考compile time 和 run time的区别,下面是一篇ibm的文档:
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/proguide/ref/cvfltar.htm

posted on 2007-11-19 14:02  lbq1221119  阅读(1609)  评论(4编辑  收藏  举报

导航