简单分析.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 作者:傅晗 责编:豆豆技术应用