随笔- 33  文章- 0  评论- 353 
本文为一些泛型反射技巧的简单罗列,为日后的文章做准备。
1、如何获得一个封闭构造类型(closed constructed type)的Type对象?
假设有如下的类型:
class TestType<T>
class TestType<T, U>
如果要获得封闭构造类型的Type对象,那么只需要用C#的typeof运算符,或者VB的GetType运算符作用于具体类型即可:
//C#
Type t1 = typeof(TestType<int>);
'VB
Dim t2 As Type = GetType(TestType(Of String))

2、如何获取一个泛型类型(generic type)的Type对象?
所谓泛型类型,就是有类型参数,但类型参数还未指定的原始定义。我们不能用TestType<T>这样的语法,因为T在我们的上下文中不存在。这时,可以用空的尖括号(C#)或空的Of语句(VB)来获取。
Type t1 = typeof(TestType<>);
Type t2 
= typeof(TestType<,>);
Dim t1, t2 As Type
t1 
= GetType(TestType(Of ))
t2 
= GetType(TestType(Of ,))
注意,我们可以用逗号来区别类型参数的个数。这就表明,泛型类型只能按类型参数的多少来重载,而不管有何种约束之类。这里获得的Type,就是类型参数未指定的泛型类型。

3、如何从构造类型的Type对象生成泛型类型的Type对象?
Type类的新增方法可以做到。
//C#
Type ct = typeof(List<int>);

//Get generic type definition
Type gt = ct.GetGenericTypeDefinition();

4、如何获取类型参数的Type对象?
泛型类型的T, U等类型参数,以及运行中的实际取值,都是可以从Type对象获取的。
'VB
Dim t As Type = GetType(List(Of Integer))

'Get the generic arguments, an array
Dim typeArgs As Type() = t.GetGenericArguments()
'Get the first argument: Integer in this case
Dim tArg0 As Type = typeArgs(0)

5、从泛型类型Type对象生成构造类型的Type对象。
通常可以用来从一种构造类型生成另一种构造类型
//C#
Type ct = typeof(List<int>);
Type gt 
= ct.GetGenericTypeDefinition();

//Make another constructed type
//The List<string> in this case
Type ct2 = gt.MakeGenericType(typeof(string));

6、如何取一个开放构造类型(open constructed type)的Type对象?
开放构造类型是最难处理的一个,因为他们的类型参数已经指定,但没有指定为具体类型,而是指定为其他泛型类型的类型参数。这种类型在进行反射重载选取以及反射发出(Reflection Emit)操作的时候尤为重要。我们的手法就是,先从宿主泛型类型的定义中获取类型参数的类型,然后再建造出开放构造类型。这里,我们获得List<T>的构造函数的参数,IEnumerable<T>的类型,注意这里的T是List<T>所定义的,而不是泛型IEnumerable<T>自己的类型参数
'The generic type of List(Of T)
Dim tlist As Type = GetType(List(Of ))

'Get the "T" of List(Of T)
Dim typeParam As Type = tlist.GetGenericArguments()(0)

'the generic type of IEnumerable(Of T)
Dim tienum As Type = GetType(IEnumerable(Of ))

'make the open constructed type
Dim tienumOpen As Type = tienum.MakeGenericType(typeParam)

'只有用这种方法获得开放构造类型
'
你才能用这个语法获得真正想要的构造函数定义
'
因为构造函数定义里IEnumerable(Of T)是一个开放构造类型
Dim c As ConstructorInfo = _
    tlist.GetConstructor(
New Type() {tienumOpen})

大家可以回去结合试验理解这些用法。
 posted on 2006-06-02 08:48 装配脑袋 阅读(3262) 评论(11)  编辑 收藏 网摘

#1楼    回复  引用  查看    
 idior       | 2006-06-02 09:32
好!下次用到就来查这个 :)
#2楼    回复  引用  查看    
 高海东       | 2006-06-02 09:54
hao
#3楼    回复  引用  查看    
 TerryLee       | 2006-06-02 10:54
不错,赞一个:-)
#4楼    回复  引用  查看    
 蔡克伦       | 2006-06-02 11:05
不错,好文章
#5楼    回复  引用  查看    
 涟漪勇       | 2006-06-02 16:56
收藏
#6楼    回复  引用  查看    
 丁丁       | 2006-06-03 01:43
不算支离破碎,到像cookbook,喜欢你的blog,希望日后文章能有些具体应用心得和实例(好像我很贪心啊,哈哈)
#7楼    回复  引用  查看    
 a_a       | 2006-07-30 07:01
同楼上,虽然这些条目都一知半解地看懂了,但还想不出在实际开发中怎么用上,期盼您的后续文章。
#8楼    回复  引用  查看    
 没剑       | 2008-01-02 23:29
先收下来了, 日后用到的话再翻来看,哈哈
#9楼    回复  引用  查看    
 JacksonLin       | 2008-11-30 23:40
文章不错,blog内容不错.继续支持
#10楼    回复  引用    
 木只八刀[未注册用户] | 2008-12-10 15:49
您好:
因为语言描述不清楚,我写伪码说明了:
var rs=from p in db.table.AsEnumerable() selep new {...};
object o=rs;
在实际应用中, o是另一个地方的object型属性, 所以rs 已经不可用了, 现在已经有了object 型的o , 想得到IQueryable<T> 中的T , 应该怎么取得? 您的文章中提到了o.GetType().GetGenericArguments() 方法, 但是您只用了它的第一个元素, 而在这种情况下, 这个方法会返回不止一项, 而且我不知道怎么从这个数组生成 T 所代表的匿名类型. 谢谢!

#11楼    回复  引用  查看    
 周利华       | 2009-03-13 20:38
谢谢楼主的分享,但是有一些real world实际应用code就更好了。



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 415458




相关文章:

相关链接: