简单分析.net泛型中的类型参数

http://tech.ddvip.com   2008年09月06日    社区交流

本文详细介绍简单分析.net泛型中的类型参数

  一位朋友询问tppeof、GetType()、is、as的问题,在实验的时候顺手就用泛型写的例子。在看Jit后的反汇编时发现了一个问题,clr对泛型参数有些特殊处理。上网查了一下没有找到介绍泛型参数存储的文章因此动手做了一番实验,有了些浅显的理解在此记录下来望看到此文的高手能给予全面的解释。

  以前用泛型的时候没想过clr是如何处理泛型参数的,今天查阅了下<<Expert .NET 2.0 IL Assembler>>里面讲解了一个叫做GenericParam Metadata Table的数据结构,不过没能解决我的疑惑。先来看段代码:

class C<T, U, V> where T: class
  {
    public void Test_Class(V v)
    {
      Debugger.Break();
      T t = v as T;
    }
    public void Test_Method<X, Y>(X x, Y y)
    {
      Debugger.Break();
      Type type1 = typeof(X);
      Type type2 = typeof(Y);
    }
  }
class Test
{
static void Main()
{ 
C<Type, string, object> c = new C<Type, string, object>();      
      string s = "ok";
      object o = s;
      c.Test_Class(o);
      c.Test_Method(s, o);
}
}

  我们先执行Test_Class方法,当进入Test_Class方法后部分主要反汇编及注释如下:

T t = v as T;
0000003e mov     eax,dword ptr [ebp-3Ch] //1.得到this指针                       01E52B30
00000041 mov     eax,dword ptr [eax]      //2.得到C<T, U, V>的方法表地址        002A3918
00000043 mov     eax,dword ptr [eax+20h] //3.得到存储泛型参数的地址            002A3954
00000046 mov     eax,dword ptr [eax]     //4.保存参数类型的地址                002a3958
00000048 mov     eax,dword ptr [eax]     //5.得到T参数的真实类型,既方法表地址 6C18172C
0000004a mov     dword ptr [ebp-48h],eax
0000004d test    dword ptr [ebp-48h],1
00000054 jne     0000005B
00000056 mov     ecx,dword ptr [ebp-48h] //将T的方法表地址传给ECX准备call as方法
00000059 jmp     00000061
0000005b mov     eax,dword ptr [ebp-48h]  
0000005e mov     ecx,dword ptr [eax-1]
00000061 mov     edx,dword ptr [ebp-40h] //得到参数o
00000064 call    6C0598F3              //调用as方法

来源:blog.csdn    作者:傅晗    责编:豆豆技术应用

正在加载评论...