TypeInfo和Type的区别与选择

概念 

TypeInfo出现于.net framework 4.5之后,这次调整用于区分两个概念:“reference”和“definition”。

reference is a shallow representation of something

definition is  a rich representation of something

例如System.Reflection.Assembly就代表了一个“definition” ,而System.Reflection.AssemblyName就代表了一个“reference

在未区分这两种概念之前,System.Type是这两种概念的混合,通过一个Type实例,既可以获得该类型的“Name、Assembly、……”,也可以获得该类型的“NestTypes、Fields、Properties、Methods、Constructors、Events……”。这也导致了当我们获得一个Type的时候,就把它全部的信息都加载到了内存中,但是很多情况下,这并不是我们想要看到的。举例如下:

public MyClass:BaseClass{

}

//获得MyClass的类型对象

Type t=MyClass.GetType();

 在.net framework 4中,获得类型对象时,同时获得了基类(BaseClass)的类型对象,同时包括基类对象的“reference”和“definition”,因此需要把基类所在的程序集也加载进来。

在.net framework 4.5中,如下代码:

Type baseType = MyClass.GetType().GetTypeInfo().BaseType;

 在获得类型对象时,只获得了基类的"reference"

使用

在明确概念后,具体什么属性和方法属于"definition",什么属性和方法属于"reference",我并没有很清晰,以下只是做一个粗糙的说明。

最简单的理解就是:System.Reflection.TypeInfo中的属性和方法即是"definition",而去除掉System.Type中与TypeInfo重合的部分,剩下的即是"reference"。

简单比较一下可以发现:

扫描二维码关注公众号,回复: 4806859 查看本文章
public class Type:MemberInfo
{
    public bool Is*();
    public MemberInfo[] GetMembers();
    public virtual MemberInfo[] GetMember(string name, BindingFlags bindingAttr);
}

public class TypeInfo:Type
{
    public IEnumerable<MemberInfo> DeclaredMembers{get;}
}

下面针对以上代码,从以下几个角度进行说明:

类型继承:TypeInfo继承自Type,但实际上

右图才是真正实现了概念分离的代码结构,现在的设计,只是为了兼容之前的版本

返回内容:

Get*()返回的是当前类型定义的MemberInfo以及其基类的public类型的MemberInfo

Declear*属性返回的是当前类型定义的Member Info

返回数据类型:

Get*()返回的是Array类型

Declear*属性返回的是IEnumerable<>类型,此类型具有延迟加载的功能,因为如果要返回Array类型,必须将Array填满后返回,而IList和IEnumerable只是实现了一个状态机,这里没有使用IList的原因是,IEnumerable更加简洁

 返回数据过滤

Get*()方法含有BindingFlags参数,用来选择返回的MemberInfo是Public还是Static...

Declear*()的方法并不含有BindingFlags参数,因此需要使用LINQ进行查询过滤

猜你喜欢

转载自blog.csdn.net/fengsocool/article/details/85927995
今日推荐