在.net framework 2.0中引入了范型(generic)的概念,这可以说是一个重大的改进它的好处我在这里也不用多说,到网上可以找到非常多的说明。
我在这里要和大家说的是怎么通过反射使用范型的技术。
一:首先看看范型的fullname
list<string> list = new list<string>();
system.console.writeline(list.gettype().fullname);
system.console.writeline();
这个语句得到的是:
system.collections.generic.list`1[[system.string, mscorlib, version=2.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089]]。
好长呀,分析一下其中的格式会看出一下几个东东。
system.collections.generic.list -> 说明该type是什么类型的。
1、-> 应该是范型的标志。
system.string, mscorlib, version=2.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089 ->是string类型的fullname。
那么在看看这个语句会出现什么?
dictionary<string, int> dic = new dictionary<string, int>();
system.console.writeline(dic.gettype().fullname);
system.console.writeline();
结果是:
system.collections.generic.dictionary`2[[system.string, mscorlib, version=2.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089],[system.int32, mscorlib, version=2.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089]]。
更长,分析一下:
system.collections.generic.dictionary -> 说明该type是什么类型的。
2 -> 还是是范型的标志。
system.string, mscorlib, version=2.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089 ->是string类型的fullname。
system.int32, mscorlib, version=2.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089 ->是int类型的fullname。
从上面的例子可以看出范型的类型和1.1时增加了两个部分,分别是范型的标识部分和范型的参数类型fullname部分。
首先看一下标志部分 `1和`2,猜测`标识了该类型是范型、后面的数字部分是说明了该范型需要几个范型参数。
现在还是猜测,下面根据猜测来应用我们自己的反射试验一下吧:
二:范型反射的试验
看看下面的代码:
string tliststr = "system.collections.generic.list`1[system.string]";
type tlist = type.gettype(tliststr);
object olist = system.activator.createinstance(tlist);
methodinfo addmlist = tlist.getmethod("add");
addmlist.invoke(olist, new object[] { "zhx" });
console.writeline(olist.tostring());
system.console.writeline();
string tdicstr = "system.collections.generic.dictionary`2[[system.string],[system.int32]]";
type tdic = type.gettype(tdicstr);
object odic = activator.createinstance(tdic);
methodinfo addmdic = tdic.getmethod("add");
addmdic.invoke(odic, new object[] {"zhx",1 });
console.writeline(odic.tostring());
system.console.writeline();
测试通过。不过大家要注意了。范型中的基础类型如:string,int不能使用简写的,如果把 system.collections.generic.list`1[system.string] 写成 system.collections.generic.list`1[string]是不能够得到正确类型的。
三:自已定义的范型反射的使用
首先自己定义一个范型类:
namespace reftest
{
public class baseclass<t,v,o>
{
t t;
v v;
o o;
public void setvalue(t pt,v pv,o po)
{
this.t = pt;
this.v = pv;
this.o = po;
}
public override string tostring()
{
return string.format("t:{0} v:{1} o:{2}", t.tostring(), v.tostring(), o.tostring());
}
}
}
使用反射创建类型和调用方法:
string tbaseclassstr = "reftest.baseclass`3[[system.string],[system.int32],
[system.collections.generic.dictionary`2[[system.string],[system.int32]]]]";
type tbaseclass = type.gettype(tbaseclassstr);
object obaseclass = activator.createinstance(tbaseclass);
methodinfo addmbaseclass = tbaseclass.getmethod("setvalue");
addmbaseclass.invoke(obaseclass, new object[] {"zhx",1,odic });
console.writeline(obaseclass.tostring());
system.console.writeline();
测试成功。