前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅谈.Net反射 6

浅谈.Net反射 6

作者头像
小蜜蜂
发布2019-07-30 10:40:07
3180
发布2019-07-30 10:40:07
举报
文章被收录于专栏:明丰随笔明丰随笔

接着《浅谈.Net反射 4》文章里面的代码,我们继续。

如何进一步查看类型信息?

获取类型基本信息,定义TypeExplore:

代码语言:javascript
复制
public static void TypeExplore(Type t)
{
  StringBuilder sb = new StringBuilder();
  sb.AppendLine("TypeName:");
  sb.AppendLine("Name: " + t.Name);
  sb.AppendLine("FullName: " + t.FullName);
  sb.AppendLine("Namespace: " + t.Namespace);
  sb.AppendLine("other info:");
  sb.AppendLine("BaseType: " + t.BaseType);
  sb.AppendLine("UnderlyingSystemType: " + t.UnderlyingSystemType);
  sb.AppendLine("Type info:");
  sb.AppendLine("Attributes: " + t.Attributes);
  sb.AppendLine("IsValueType: " + t.IsValueType);
  sb.AppendLine("IsEnum: " + t.IsEnum);
  sb.AppendLine("IsClass: " + t.IsClass);
  sb.AppendLine("IsArray: " + t.IsArray);
  sb.AppendLine("IsInterface: " + t.IsInterface);
  sb.AppendLine("IsPointer: " + t.IsPointer);
  sb.AppendLine("IsSealed: " + t.IsSealed);
  sb.AppendLine("IsPrimitive: " + t.IsPrimitive);
  sb.AppendLine("IsAbstract: " + t.IsAbstract);
  sb.AppendLine("IsPublic: " + t.IsPublic);
  sb.AppendLine("IsNotPublic: " + t.IsNotPublic);
  sb.AppendLine("IsVisible: " + t.IsVisible);
  sb.AppendLine("IsByRef: " + t.IsByRef);
  Console.WriteLine(sb.ToString());
}

运行下面的代码:

代码语言:javascript
复制
Type t = typeof(DemoClass);
TypeExplore(t);

运行结果:

值得注意的是Attributes属性,它返回一个TypeAttributes位标记,这个标记标识了类型的一些元信息,可以看到熟悉的Class、Public、Sealed。相应的,IsClass、IsSealed、IsPublic等属性也返回为True。

成员信息与MemberInfo类型

对于一个类型而言,可能会包含哪些成员?常见的有字段、属性、方法、构造函数、接口、嵌套类型等。MemberInfo类代表着Type的成员类型,值得注意的是Type类本身又继承自MemberInfo类,因为一个类型经常也是另一类型的成员。

Type类提供了GetMembers()、GetMember()、FindMember()等方法用于获取某个成员类型。

添加一个方法MemberExplore():

代码语言:javascript
复制
public static void MemberExplore(Type t)
{
  StringBuilder sb = new StringBuilder();
  MemberInfo[] memberInfo = t.GetMembers();
  sb.Append("Type " + t.Name + " member info:\n");
  foreach (MemberInfo mi in memberInfo)
  {
    sb.AppendLine("memberInfo: " + mi.ToString().PadRight(40) + " memberType: " + mi.MemberType);
  }
  Console.WriteLine(sb.ToString());
}

运行下面的代码:

代码语言:javascript
复制
Type t = typeof(DemoClass);
MemberExplore(t);

运行结果:

MemberExplore()方法在Type的实例上调用了GetMembers()方法获取了成员信息的一个数组,然后遍历了数组,打印了成员的名称和类型。注意到Name属性在编译后变为了get_Name()和set_Name()两个独立的方法;myEvent事件的注册(+=)和取消注册(-=)分别成为了add_myEvent()和remove_myEvent方法。同时,发现私有字段name没有被打印出来,而基类System.Object的成员GetType()和Equals()被打印了出来。

有的时候,可能不希望查看基类的成员,也可能需要查看私有的成员,此时可以使用GetMembers()的重载方法,传入BindingFlags位标记作为参数来完成。

BindingFlags位标记对如何获取成员的方式进行控制(也可以控制如何创建对象实例)。对于本例,如果想获取所有的公有、私有、静态、实例成员,那么只需要像下面这样修改GetMembers()方法就可以了。

代码语言:javascript
复制
MemberInfo[] memberInfo = t.GetMembers(
  BindingFlags.Public |
  BindingFlags.Static |
  BindingFlags.NonPublic |
  BindingFlags.Instance |
  BindingFlags.DeclaredOnly
);

我们看一下Type类中的GetMember和GetMembers的方法签名:

代码语言:javascript
复制
public MemberInfo[] GetMember(string name)
public virtual MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
public virtual MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr)
public MemberInfo[] GetMembers()
public abstract MemberInfo[] GetMembers(BindingFlags bindingAttr);

还有一个FindMembers方法:

代码语言:javascript
复制
public virtual MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)

FindMembers可以根据MemberTypes进行查找Members信息。如果想要获取所有的方法(Method),那么可以调用Type类的FindMembers()方法:

代码语言:javascript
复制
BindingFlags flags = BindingFlags.Public |
  BindingFlags.Static |
  BindingFlags.NonPublic |
  BindingFlags.Instance |
  BindingFlags.DeclaredOnly;
MemberInfo[] memberInfo = t.FindMembers(
  MemberTypes.Method, // 说明查找的成员类型为 Method
  flags,
  Type.FilterName,
  "*"
);

MemberInfo类有两个属性值得注意,一个是DeclaringType,一个是ReflectedType,返回的都是Type类型。

DeclaredType返回的是声明该成员的类型,即可以知道该成员是定义在哪一个类里面的。例如继承自System.Object基类的Equals()方法,对于Equals()方法来说,它的DeclaringType返回的对象相当于是typeof(System.Object),因为它是在System.Object中被定义的。

而Equals()方法的ReflectedType返回的对象则相当于是typeof(DemoClass),因为它是通过DemoClass的类型实例被获取到的。

本文回顾:

类型基本信息

成员信息与MemberInfo类型

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 明丰随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档