在.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();
測試成功。