C#如何利用反射将枚举绑定到下拉框详解

前言:

反射(Reflection)是.NET提供给开发者的一个强大工具,尽管作为.NET框架的使用者,很多时候不会用到反射。但在一些情况下,尤其是在开发一些基础框架或公共类库时,使用反射会使系统架构更加灵活。

在开发中,我们常常会遇到比如有些状态值在定义好后几乎从不改动,这时候使用数据库就显得有些多余了。首先想到的一个办法可能是在程序中创建一个数组来表示,此时,我们遇到了使用数组可能带来的第一个问题:不方便使用。当数组结构变更时,可能意味着所有使用过此数组的地方的索引都发生了变更,这是我们不想看到的。

这时,我们可以采用枚举:

public enum BookingStatus
 {
 未提交 =1,
 已提交,
 已取消,
 已定妥 = 6
 }

在实际使用中,可能需要用户下拉选择这些状态值,这时就需要我们把枚举绑定到下拉框上(此处以Combobox为例)了。大家知道,可以绑定到下拉框列表的有两种类型:一种是实现了IEnumerable接口的可枚举类型,比如ArrayList,String[],List<T>;一类是实现了IListSource的数据源,比如DataTable,DataSet。

可是,枚举enum是一个基本类型,它不会实现任何的接口,显然,无法直接将枚举绑定到下拉框上,那么应该采用什么办法呢?

使用反射遍历枚举字段

要遍历枚举,首先就需要一个包含枚举每个字段信息的对象,这个对象至少应该包含两个属性,一个是字段的名称,一个是字段的值,以方便后续绑定。

先看下完整的代码:

private void Form1_Load(object sender, EventArgs e)
  {
   comboBox1.DataSource = GetDataTable();
   comboBox1.DisplayMember = "Name";
   comboBox1.ValueMember = "Value";
  }

  public static DataTable GetDataTable()
  {
   Type t = typeof(BookingStatus); //创建类型
   FieldInfo[] fieldinfo = t.GetFields(); //获取字段信息对象集合

   DataTable table = new DataTable();
   table.Columns.Add("Name", typeof(String));
   table.Columns.Add("Value", typeof(Int32));

   foreach (FieldInfo field in fieldinfo)
   {
    if (!field.IsSpecialName)
    {
     DataRow row = table.NewRow();
     row[0] = field.Name; //获取文本字段
     row[1] = (int)field.GetRawConstantValue(); //获取int数值
     table.Rows.Add(row);
    }
   }
   return table;
  }
 }

 public enum BookingStatus
 {
  未提交 =1,
  已提交,
  已取消,
  已定妥 = 6
 }

效果:

这里大致做一个说明:Type抽象类提供了访问类型元数据的能力,当实例化了一个Type对象后,可以通过它的属性和方法,获取类型的元数据的信息,或者进一步获得该类型的成员的元数据信息。注意到这里,因为Type对象总是基于某一具体类型的,并且它是一个抽象类,所以再创建Type类型时,需要提供类型名称或者类型的实例。程序集元数据,通过Type类型就可以访问类型的元数据信息,而访问类型元数据的操作,就叫做反射。

使用泛型来达到代码重用

观察上面的代码,如果现在有另一个枚举,叫做TicketStatus,那么要将它的枚举项文本和值转换为DataTable,唯一需要改动的就是这里:

Type t = typeof(BookingStatus); //将枚举名称更换

既然这样,就可以利用泛型来实现代码的重用,将返回DataTable的方法更改为泛型方法:

public static DataTable GetDataTable<T>()
  {
   Type t = typeof(T); //创建类型
   FieldInfo[] fieldinfo = t.GetFields(); //获取字段信息对象集合

   //...............省略   

   return table;
  }

从以上代码可以看出,综合使用反射,泛型等技术,可以极大地提高代码的灵活性,可重用性。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • C#中的程序集和反射介绍

    什么是程序集? 1.程序集(assembly)是一个及一个以上托管模块,以及一些资源文件的逻辑组合. 2.程序集是组件复用,以及实施安全策略和版本策略的最小单位. 3.程序集是包含一个或者多个类型定义文件和资源文件的集合.在程序集包含的所有文件中,有一个文件用于保存清单.(清单是元数据部分中一组数据表的集合,其中包含了程序集中一部分文件的名称,描述了程序集的版本,语言文化,发布者,共有导出类型,以及组成该程序集的所有文件). 4.在编译应用程序中,所创建的CIL代码存储在一个程序集中,程序集包括

  • C#中使用反射获取结构体实例及思路

    复制代码 代码如下: static void Main(string[] args){    Type type = typeof(MyObject);    object obj = type.GetConstructor(Type.EmptyTypes).Invoke(null);    Console.WriteLine(obj);} class MyObject{ } 之前我一直没有发现原来结构是不可以这样实例化的 换种方式,似乎结构体使用反射无法得到其构造函数ConstructorIn

  • 关于C#基础知识回顾--反射(一)

    反射(reflection)是一种允许用户获得类型信息的C#特性.术语"反射"源自于它的工作方式:Type对象映射它所代表的底层对象.对Type对象进行查询可以获得(反射)与类型相关的信息.反射是一种功能强大的机制,它允许学习和使用只在运行时才能知道的类型功能. 这些是官方定义,其实说白了,反射就是能知道我们未知类型的类型信息这么一个东西.没什么神秘可讲!反射的核心是System.Type.System.Type包含了很多属性和方法,使用这些属性和方法可以在运行时得到类型信息.一旦得到

  • C# 遍历枚举类型的所有元素

    比如定义了一个错误的枚举类型 复制代码 代码如下: public enum eErrorDetailCode : int         {             登陆成功 = 0,             登出 = 1,             应用错误 = 2,             成功 = 16,             失败 = 17         } 需要引用 using System; 然后在循环中,遍历枚举对象的所有元素 复制代码 代码如下: foreach (int  m

  • C#利用反射来判断对象是否包含某个属性的实现方法

    本文实例展示了C#利用反射来判断对象是否包含某个属性的实现方法,对于C#程序设计人员来说有一定的学习借鉴价值. 具体实现代码如下: /// <summary> /// 利用反射来判断对象是否包含某个属性 /// </summary> /// <param name="instance">object</param> /// <param name="propertyName">需要判断的属性</par

  • C#反射技术的简单操作(读取和设置类的属性)

    要想对一个类型实例的属性或字段进行动态赋值或取值,首先得得到这个实例或类型的Type,微软已经为我们提供了足够多的方法. 首先建立一个测试的类 复制代码 代码如下: public class MyClass { public int one { set; get; } public int two { set; get; } public int five { set; get; } public int three { set; get; } public int four { set; ge

  • c#使用反射调用类型成员示例

    在实际的工作中直接使用反射的机会比较少,有印象的就是一次自己做的WinForms小工具的时候利用反射来动态获取窗体上的每个控件,并且为必要的控件动态添加注册事件.因为刚入职新公司,为了更快的了解公司的业务.和开发习惯,先和现在公司同事一起修改现有系统的一些小Bug.在Tester提交的Bug中有一个是对GridView进行动态的排序--点击一个列时使用该列作为条件进行排序(PS:点击一个列时前台会将该列的字符串(该字符串是)传到后台的方法中). 使用反射的原因 为什么会选择使用反射呢?在项目中我

  • C#反射的一些应用

    对于反射贫道也是很陌生的,所以趁现在有时间就把反射看了一下,记下笔记!!!反射的定义:反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的名称.限定符和参数等.有了反射,即可对每一个类型了如指掌.如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道.  1,导入using System.Reflection;  2,Asse

  • c#反射机制学习和利用反射获取类型信息

    1..NET可执行应用程序结构 程序代码在编译后生成可执行的应用,我们首先要了解这种可执行应用程序的结构. 应用程序结构分为应用程序域-程序集-模块-类型-成员几个层次,公共语言运行库加载器管理应用程序域,这种管理包括将每个程序集加载到相应的应用程序域以及控制每个程序集中类型层次结构的内存布局. 程序集包含模块,而模块包含类型,类型又包含成员,反射则提供了封装程序集.模块和类型的对象.我们可以使用反射动态地创建类型的实例,将类型绑定到现有对象或从现有对象中获取类型,然后调用类型的方法或访问其字段

  • c#反射调用方法示例

    获取方法的相关信息的两种形式 反射是一种允许用户获得类信息的C#功能,Type对象映射它代表的底层对象: 在.Net 中, 一旦获得了Type对象,就可以使用GetMethods()方法获取此类型支持的方法列表:该方法的两种形式: MethodInfo [] GetMethods() MethodInfo [] GetMethods(BindingFlags bindingflas)  :它的参数带有一些限制 BindingFlags  是一个枚举 枚举成员 [DeclaredOnly,Inst

随机推荐