.NET 4.5(C#):TypeInfo类型和反射中的成员枚举

来自:http://www.cnblogs.com/mgen/archive/2012/06/24/2560234.html

先说类型中成员的枚举,传统的Type类型的成员枚举会返回public,static或者非static的成员,这个可以由BindingFlags枚举设置,因此无论是枚举全部成员还是根据名称返回一个成员,甚至是用Type来限制类型,默认的BindingFlags是这样的:

BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public

 

在.NET 4.5中,加入了另一种快捷的方法(当然在.NET 4.5之前也可以这样做,只不过需要手动设置BindingFlags),通过使用System.Reflection中RuntimeReflectionExtensions类型提供的扩展方法,返回的成员是这样类型的:

BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic

 

可以看到,NonPublic类型被加入。也就是私有成员也会被返回。

 

RuntimeReflectionExtensions的方法命名都是GetRuntimeXXX的方式。当然也有一些方法跟BindingFlags没有关系,比如GetMethodInfo就是返回Delegate.Method属性。

image

 

同时RuntimeReflectionExtensions的方法都会确定Type类型是RuntimeType类型,否则会抛出ArgumentException,同时RuntimeReflectionExtensions.GetRuntimeBaseDefinition方法还会验证MethodInfo是RuntimeMethodInfo类型。

 

.NET 4.5还有另一种成员枚举的方法,通过一个新的类型,同样在System.Reflection命名空间中,他是TypeInfo类型。TypeInfo类型影响了.NET 4.5中的类型的执行。首先一个新接口:IReflectableType,只有一个方法,GetTypeInfo返回一个TypeInfo对象。其实IReflectableType类型或多或少有点像.NET 4.5之前的IReflect接口。

 

他有一个执行类,就是TypeInfo类型本身:

image

 

TypeInfo类型继承自Type,然后执行IReflectableType,他的GetTypeInfo方法的执行就是返回自己。如下,TypeInfo类型的定义:

//在System.Reflection

public abstract class TypeInfo : TypeIReflectableType

 

最后内部的RuntimeType类继承关系也改变了,.NET 4.5之前是继承自Type类型,而.NET 4.5中他是继承自TypeInfo类型,当然仍然间接继承自Type类型。

internal class RuntimeType : TypeInfoISerializableICloneable

 

而TypeInfo也提供了类似上述模式的类型成员返回或者说枚举方式,但是它内部使用的BindingFlags是:

BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |BindingFlags.NonPublic

 

相比RuntimeRefelctionExtensions,增加了DeclaredOnly,也就是说只有定义的成员才会被返回。

因此TypeInfo的方法都是类似GetDeclaredXXX的命名:

image

 

TypeInfo同时定义其他辅助方法,比如AsType把自己重新转换成Type(当然子类往父类的转换本来就是隐世的,可以能为了方便去掉其相关的扩展方法?),还有常用的IsAssignableFrom,可以直接和另一个TypeInfo做比较。

 

那么怎样从Type获取TypeInfo呢?简单,判断Type是否执行IReflectable,是的话,返回IReflectable.GetTypeInfo。当然,这个步骤在.NET 4.5已经有了扩展方法的定义,在RuntimeReflectionExtensions.GetTypeInfo方法中。

 

 

OK,写了这么多,来练习一下,定义两个非常简单的有继承关系的类型:

//b继承a,每一个类型内有一个public属性和private属性

class a

{

    public int Prop1 { getset; }

    int PrivateProp1 { getset; }

}

class ba

{

    public int Prop2 { getset; }

    int PrivateProp2 { getset; }

}

 

注意加入System.Reflection命名空间,这样所有扩展方法能工作:

using System.Reflection;

 

 

好,首先用最传统方法:

foreach(var pi in typeof(b).GetProperties())

    Console.WriteLine(pi.Name);

 

类型b的所有公共成员会被输出:

Prop2

Prop1

 

第二种方法,通过RuntimeReflectionExtensions.GetRuntimeProperties方法。

//通过RuntimeReflectionExtensions.GetRuntimeProperties

foreach(var pi in typeof(b).GetRuntimeProperties())

    Console.WriteLine(pi.Name);

 

b类型的所有成员会被输出:

Prop2

PrivateProp2

Prop1

 

最后就是通过TypeInfo:

//通过TypeInfo

foreach (var pi in typeof(b).GetTypeInfo().DeclaredProperties)

    Console.WriteLine(pi.Name);

 

b类型的所有本类定义的属性会被显示:

Prop2

PrivateProp2

作者:Mgen 
出处:www.cnblogs.com/mgen 
其他参考页面:我的软件和工程博客导读


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值