zoukankan      html  css  js  c++  java
  • 【点滴积累】在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 中的反射

  • 相关阅读:
    image 和 barplot 的组合
    par函数mgp 参数-控制坐标轴的位置
    R语言绘图时的边界碰撞问题
    R语言绘制花瓣图flower plot
    mothur 计算稀释性曲线
    R语言 vegan包计算物种累计曲线
    R语言数据框小技巧
    tophat-fusion 鉴定融合基因
    FusionCancer-人类癌症相关的融合基因的数据库
    rrnDB数据库简介-16S基因多拷贝数的证据
  • 原文地址:https://www.cnblogs.com/IPrograming/p/reflection_dynamic_Invoke.html
Copyright © 2011-2022 走看看