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

浅谈.Net反射 1

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

反射前传-遍历枚举类型

本文不会深入讲解反射,只是完成一个小功能:遍历枚举类型。在后续的文章里会具体讲解反射技术。

在.NET中,提供了System.Type类和System.Reflection命名空间来帮助我们实现这个功能。

Type抽象类提供了访问类型元数据的能力,当实例化了一个Type对象后,可以通过它的属性和方法,获取类型的元数据信息,或者进一步获得该类型的成员的元数据信息。

注意到这里,因为Type对象总是基于某一具体类型的,并且它是一个抽象类,所以在创建Type对象时,需要提供具体类型的名称或者具体类型的实例。

首先创建一个枚举类型WeekDay:

代码语言:javascript
复制
public enum WeekDay
{
  [Description("This is 1st of week.")]
  Monday = 1,
  [Description("This is 2st of week.")]
  Tuesday,
  [Description("This is 3st of week.")]
  Wednesday,
  [Description("This is 4st of week.")]
  Thursday,
  [Description("This is 5st of week.")]
  Friday,
  [Description("This is 6st of week.")]
  Saturday,
  [Description("This is 7st of week.")]
  Sunday
}

里面有枚举字段的值,字段名称,和描述信息。

通过下面的方法可以获取枚举中的所有值:

代码语言:javascript
复制
//获取枚举类型的枚举值
public static List<EnumItem> GetEnumItems()
{
  List<EnumItem> items = new List<EnumItem>();
  //typeof运算符得到具体类型的Type对象
  Type type = typeof(WeekDay);
  //调用Type对象的GetFields()方法,返回Type对象所表示的具体类型中定义的所有字段
  var fields = type.GetFields();
  foreach (var field in fields)
  {
    //过滤掉具体类型中系统自带的一些特殊字段
    if (!field.IsSpecialName)
    {
      EnumItem item = new EnumItem();
      //获取具体类型中定义的字段的静态值,即枚举的值
      item.Value = (int)field.GetRawConstantValue();
      //获取具体类型中定义的字段的名称
      item.Name = field.Name;
      //获取具体类型中定义的字段的Description特性值
      item.Description = string.Empty;
      var descrAttr = field.GetCustomAttribute<DescriptionAttribute>();
      if (descrAttr != null)
      {
        item.Description = descrAttr.Description;
      }

      items.Add(item);
    }
  }

  return items;
}

代码中,使用了Type对象,FieldInfo对象,DescriptionAttribute对象,通过它们得到了枚举类型中的所有值。

我们再定义一个枚举类型Months:

代码语言:javascript
复制
public enum Months
{
  January = 1,
  February,
  March,
  April,
  May,
  June,
  July,
  August,
  September,
  October,
  November,
  December
}

我们想遍历Months类型的枚举值,和上面的WeekDay类型的代码一模一样,除了这一行:

代码语言:javascript
复制
//typeof运算符得到具体类型的Type对象
Type type1 = typeof(WeekDay);
Type type2 = typeof(Months);

定义泛型类重用GetEnumItems()代码:

代码语言:javascript
复制
//使用泛型类达到代码重用
public class EnumManager<TEnum>
{
  //使用静态构造器,约束泛型只能是枚举类型
  //使用非枚举类型,编译可以通过,但是运行时会拋异常
  static EnumManager()
  {
    if (!typeof(TEnum).IsEnum)
    {
      throw new ArgumentException("TEnum must be an enumerated typeof.");
    }
  }
  //获取枚举类型的枚举值
  public static List<EnumItem> GetEnumItems()
  {
    List<EnumItem> items = new List<EnumItem>();
    //typeof运算符得到具体类型的Type对象
    Type type = typeof(TEnum);
    //调用Type对象的GetFields()方法,返回Type对象所表示的具体类型中定义的所有字段
    var fields = type.GetFields();
    foreach (var field in fields)
    {
      //过滤掉具体类型中系统自带的一些特殊字段
      if (!field.IsSpecialName)
      {
        EnumItem item = new EnumItem();
        //获取具体类型中定义的字段的静态值,即枚举的值
        item.Value = (int)field.GetRawConstantValue();
        //获取具体类型中定义的字段的名称
        item.Name = field.Name;
        //获取具体类型中定义的字段的Description特性值
        item.Description = string.Empty;
        var descrAttr = field.GetCustomAttribute<DescriptionAttribute>();
        if (descrAttr != null)
        {
          item.Description = descrAttr.Description;
        }

        items.Add(item);
      }
    }

    return items;
  }
}

上面的代码GetEnumItems()方法就可以给所有的枚举类型使用了,达到了代码复用的目的,再说明一点,我们使用了静态构造器对泛型类型参数进行了约束,使类型参数只能是枚举类型才能正常工作。

本文回顾:

遍历枚举类型

泛型类达到代码重用

约束泛型类型只能是枚举类型

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

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

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

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

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