【点滴积累】在C#中使用反射动态调用类型成员

简介:

1.背景

  学习C#的时候就知道使用反射可以对我们编程提供极大的便利(动态的获取信息、调用类型成员、创建实例等等),但是在实际的工作中直接使用反射的机会比较少,有印象的就是一次自己做的WinForms小工具的时候利用反射来动态获取窗体上的每个控件,并且为必要的控件动态添加注册事件。因为刚入职新公司,为了更快的了解公司的业务、和开发习惯,先和现在公司同事一起修改现有系统的一些小Bug。在QA提交的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 中的反射

 

本文转自gyzhao博客园博客,原文链接:http://www.cnblogs.com/IPrograming/archive/2013/05/25/reflection_dynamic_Invoke.html ,如需转载请自行联系原作者
相关文章
|
3月前
|
存储 安全 编译器
C# 11.0中的泛型属性:类型安全的新篇章
【1月更文挑战第23天】C# 11.0引入了泛型属性的概念,这一新特性为开发者提供了更高级别的类型安全性和灵活性。本文将详细探讨C# 11.0中泛型属性的工作原理、使用场景以及它们对现有编程模式的改进。通过深入了解泛型属性,开发者将能够编写更加健壮、可维护的代码,并充分利用C#语言的最新发展。
|
7月前
|
编译器 C#
C#之十七 局部类型
C#之十七 局部类型
17 0
|
1月前
|
存储 C# 开发者
C#变量类型
C#变量类型
19 0
|
3月前
|
开发框架 .NET 编译器
C# 9.0中的目标类型新表达式:类型推断的又一进步
【1月更文挑战第16天】C# 9.0引入了目标类型新表达式,这是类型推断功能的一个重要扩展。通过目标类型新表达式,开发者在创建对象时可以省略类型名称,编译器会根据上下文自动推断所需类型。这一特性不仅简化了代码编写,还提高了代码的可读性和维护性。本文将详细介绍目标类型新表达式的语法、使用场景及其对C#编程的影响。
|
3月前
|
存储 C# 容器
掌握 C# 变量:在代码中声明、初始化和使用不同类型的综合指南
变量是用于存储数据值的容器。 在 C# 中,有不同类型的变量(用不同的关键字定义),例如: int - 存储整数(没有小数点的整数),如 123 或 -123 double - 存储浮点数,有小数点,如 19.99 或 -19.99 char - 存储单个字符,如 'a' 或 'B'。Char 值用单引号括起来 string - 存储文本,如 "Hello World"。String 值用双引号括起来 bool - 存储具有两个状态的值:true 或 false
37 2
|
3月前
|
设计模式 C#
C#反射机制实现开闭原则的简单工厂模式
C#反射机制实现开闭原则的简单工厂模式
18 0
|
3月前
|
存储 安全 算法
C# 泛型:类型参数化的强大工具
【1月更文挑战第7天】本文将深入探讨C#语言中的泛型编程,包括泛型的定义、用途、优势以及实际应用。通过类型参数化,泛型允许开发者编写更加灵活且可重用的代码,同时提高程序的类型安全性和性能。本文将通过示例代码和详细解释,帮助读者更好地理解泛型在C#中的重要性和实用性。
|
4月前
|
存储 Java C#
【从Java转C#】第七章:运算符和类型强制转换
【从Java转C#】第七章:运算符和类型强制转换
|
4月前
|
Java 编译器 C#
【从Java转C#】第三章:对象和类型
【从Java转C#】第三章:对象和类型
|
4月前
|
存储 C# 开发者
C# | 通过反射将对象属性展示在TreeView中
在编程过程中,我们经常需要处理复杂的对象和数据结构。将这些数据结构展示在UI界面上是很有用的,可以帮助开发者更好地理解和分析数据。 而TreeView作为一种常见的控件,可以以树状结构的方式展示数据,非常适合用于展示层次化的对象。 本文将介绍如何使用TreeView控件展示一个对象,并且可以动态处理对象中的属性和子对象。通过本文的学习,您将学会如何更好地理解和展示数据,提高编程效率。
34 0
C# | 通过反射将对象属性展示在TreeView中