【点滴积累】在C#中使用反射动态调用类型成员
2013-06-09 21:08
483 查看
1.背景
学习C#的时候就知道使用反射可以对我们编程提供极大的便利(动态的获取信息、调用类型成员、创建实例等等),但是在实际的工作中直接使用反射的机会比较少,有印象的就是一次自己做的WinForms小工具的时候利用反射来动态获取窗体上的每个控件,并且为必要的控件动态添加注册事件。因为刚入职新公司,为了更快的了解公司的业务、和开发习惯,先和现在公司同事一起修改现有系统的一些小Bug。在Tester提交的Bug中有一个是对GridView进行动态的排序——点击一个列时使用该列作为条件进行排序(PS:点击一个列时前台会将该列的字符串(该字符串是)传到后台的方法中)。2.使用反射的原因
为什么会选择使用反射呢?在项目中我们使用NHibernate作为ORM框架,一般情况下在BLL层其实都提供了对应的排序方法,但是现在需要修改的这个Bug使用的数据不是在一张表里面,而是一个视图。如果按照以前排序功能实现模式的话,需要在多个地方进行修改;且由于是刚接触这个项目,对项目的结构还不够了解,不宜进行大面积的修改。和同事沟通后决定使用反射来实现。理由如下:因为是直接对已经从数据库返回的结果进行排序,所有只需要在一个地方修改(BLL层)
虽然使用反射会增加性能上的开销,但是在这个场景数据量并不大,性能上的消耗可以忽略不计
3.使用反射动态调用代码
反射给人感觉好像很复杂,其实使用起来还是比较方便的,由于项目中代码上下文牵涉过多,不适合贴出来,下面是使用我自己整理的使用反射进行动态调用,常用的一些代码片段:1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Type type = typeof(Employee); 6 7 //使用无参构造函数动态创建对象 8 var objNull = type.InvokeMember(null, BindingFlags.CreateInstance, null, null, null); 9 10 //调用两个使用了两个string参数的构造函数动态创建对象 11 var frankJob = type.InvokeMember(null, BindingFlags.CreateInstance, null, null, new object[] { "job", "frank" }); 12 13 //调用公有成员属性get方法 14 var fileName = type.InvokeMember("FirstName", BindingFlags.GetProperty, null, frankJob, null); 15 16 //调用公有成员属性set方法 17 type.InvokeMember("Email", BindingFlags.SetProperty, null, frankJob, new object[] { "gyzhao@vervidian.com" }); 18 19 //动态调用无参数方法 20 var objStr = type.InvokeMember("ToString", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static, null, frankJob, null); 21 22 //动态调用带参数的方法 23 var email = type.InvokeMember("GetEmail", BindingFlags.InvokeMethod, null, frankJob, new object[] { "sunshine" }); 24 } 25 26 public class Employee 27 { 28 public int Id { get; set; } 29 public string FirstName { get; set; } 30 public string LastName { get; set; } 31 public string Address { get; set; } 32 public string Email { get; set; } 33 34 public Employee() { } 35 public Employee(string firstName, string lastName) 36 { 37 FirstName = firstName; 38 LastName = lastName; 39 } 40 41 public override string ToString() 42 { 43 return string.Format("{0} {1}", LastName, FirstName); 44 } 45 46 public string GetEmail(string user) 47 { 48 return string.Format("{0}@gmail.com", user); 49 } 50 } 51 }
参考资料&进一步阅读
.NET Framework 中的反射相关文章推荐
- 【点滴积累】在C#中使用反射动态调用类型成员
- c#使用反射调用类型成员示例
- c#使用反射调用类型成员示例
- 反射之动态获取类型成员并执行调用
- C# 直接调用vs 委托vs动态调用vs动态类型vs反射,最佳性能测试
- C# 高级应用--反射动态调用类的成员范例 !
- C#反射动态调用dll中的方法及使用QuartZ.net实现作业调度
- 使用反射调用类型成员 方法,字段,属性
- 【经典实例】利用C#反射动态编译代码,创建类的实例,并调用其成员
- [c#美味] 使用反射动态创建实例并调用方法
- 解析如何使用反射调用类型成员 方法,字段,属性
- c#关于反射与特性《一》---动态调用成员
- C# 使用反射动态调用泛型方法
- 使用反射动态调用类成员
- 使用C#反射实现用户控件调用父页面方法
- VS2013 C#调用EXCEL 编译报错:找不到编译动态表达式所需的一个或多个类型。是否缺少引用?
- 使用反射-动态创建对象及调用对象方法
- (C#)利用反射动态调用类成员[转]
- C#利用反射动态调用类成员
- 使用反射动态调用类成员,需要Type类的一个方法:InvokeMember。对该方法的声明如下(摘抄于MSDN):