装配中的脑袋

用程序装配大脑,再用大脑装配程序
随笔 - 118, 评论 - 1214, 引用 - 11

导航

关于

如果想发较大的信件,请用Ninputer @ gmail.com

不要在我的Blog评论中张贴广告,除非同意向我付款。

标签

每月存档

最新留言

广告

 
本文为一些泛型反射技巧的简单罗列,为日后的文章做准备。
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})

大家可以回去结合试验理解这些用法。

打印 | 张贴于 2006-06-02 08:49:00 | Tag:技术随笔

留言反馈

#Acknowledgement of Community Contributions 编辑




O time de VB.Net reconheceu os principais MVP´s contribuidores de&nbsp;VB.Net no mundo! Estou...
2007-08-05 21:02:00 | [匿名:Alexandre Tarifa]
#回复: 一些支离破碎的泛型反射技巧 编辑
问一个问题,你研究过根据泛型名称和接口,反射出实例来的吗?

比如有interface IBuilde<T> where T:class
和子类名 "aBuilder"要反射出abuilder来.
2007-04-27 18:27:00 | [匿名:Simon]
#请教前辈关于程序调试的问题 编辑
前辈,您好~最近调试一个.net程序的时候遇到了麻烦,请教一下。我在VS2003环境下调试一个VB.net的程序,这个程序在Debug模式下,稳定运行一段时间之后,常常会莫名其妙地down掉,集成环境没有提示发现异常。程序日志也没有提示错误的地方。花了很长时间检查代码,但是感觉一点儿头绪都没有。
前辈能够给一些建议么?
2006-10-13 09:29:00 | [匿名:fere]
#读你《Visual Basic 2005新功能点评(一)——带有不同可见性级别访问器的属性 》 编辑
这两天看你的文章受益匪浅,你写的内容质量很高。让我这样的初学者很受益,谢谢。

我想问一下这个属性的作用,实在是搞不清楚。
比如我创建如下代码:

public class aa
public bb as string
end class

public class cc
dim dd as string

public property M_DD as string
Get
Return dd
End Get
Set(ByVal value As String)
dd = value
End Set
End Property
end class


然后我在另一个类中分别创建这两个类的实例
public class ee

dim a as new aa
dim c as new cc

a.bb="BBBB"
c.M_DD="DDDD"
debug.writeline(a.bb)
debug.writeline(c.M_DD)
end class

结果都会打印出来,我想知道这两种有什么区别?表面现象都一样啊,而且地一种不用属性的更简单。
2006-09-07 15:58:00 | [匿名:白雪峰]
#re: 一些支离破碎的泛型反射技巧 编辑
GOOD JOB!
2006-07-11 17:36:00 | [匿名:阿赖.com]
#re: 一些支离破碎的泛型反射技巧 编辑
这次我是一楼
等下要买杯可乐祝一下
我最喜欢看Ninputer 的BLOG了
我得到关VB的更多信息,我想最集中的就是这里了,
希望看到更多Ninputer 文章~!
2006-06-12 14:59:00 | [匿名:小弟打杂的]
对不起,目前本随笔不允许发表新评论.

Powered by: Joycode.MVC引擎 0.5.2.0