Reflection(反射)是深入学习.Net必须掌握的技能之一。最初学Reflection的时候,的确是被惊住了,原来还可以这样。只要给你一个Assembly, 你就能获取到其中所有的类型,根据类型,你能够创建和操作对象的属性和方法,甚至是私有的。但是,每次使用Reflection,看着那些丑陋难懂的代码,都让人不敢直视。下面就介绍一些在特定场景下可以替换Reflection的方法。

1. 使用Reflection完成的简单Demo

我们首先创建一个Person类,这个类非常简单,一个Name的public属性,一个_age的私有变量。完整代码如下:

public class Person
{private readonly int _age;public Person(int age){_age = age;}public string Name { get; set; }public bool GuessAge(int age){return _age == age;}
}

接下来,看看常规的使用reflection获取一个person对象公开属性,私有变量同时调用对象的方法:

var type = p.GetType();
var property = type.GetProperty("Name");//根据名称获取类型属性
Console.WriteLine(property.GetValue(p).ToString());//获取对象的属性值
var field = type.GetField("_age", BindingFlags.NonPublic | BindingFlags.Instance);//获取私有变量_age, 后面的BindingFlags非常重要,否则默认是不能够取到private的东西
Console.WriteLine(field.GetValue(p));
var guessResult = type.InvokeMember("GuessAge", BindingFlags.InvokeMethod, null, p, new object[] { 20 });//调用对象的方法
Console.WriteLine(guessResult);

来看看输出结果:

2. 使用PrivateObject

什么是PrivateObject, PrivateObject是微软在单元测试中引入的,本意是方便我们写单元测试的时候,对于私有变量,方法,能够非常简单方便的调用。但是这也不妨碍我们在开发代码中使用。使用PrivateObject只需要引用Microft.VisualStudio.QualityTools.UnitTestFramework

接下来看看,如何使用PrivateObject来实现:

var privateObject = new PrivateObject(p);
Console.WriteLine(privateObject.GetProperty("Name"));
Console.WriteLine(privateObject.GetField("_age"));Console.WriteLine(privateObject.Invoke("GuessAge", new object[] { 20 }));

上面的代码和使用Reflection的效果完全一样。是不是觉得整个世界都清净许多。在代码的可读性上面,比Reflection好不少。

3. 使用dynamic

使用动态类型,可以非常简单方便的访问对象的属性的方法,比如上面的代码,如果我用dynamic实现:

dynamic person = p;
Console.WriteLine(person.Name);
//Console.WriteLine(person._age);
Console.WriteLine(person.GuessAge(20));

使用dynamic的前提是,你在写代码的时候,就需要知道该对象的确切的属性名字和方法名,不能作为参数传递。而上面的Refelction和PrivateObject是可以的。
使用dynamic还有一个缺点,就是无法访问到对象的私有成员。这也是注释掉_age输出的原因。

真实的使用场景是,可以在不需要定义接口的情况下,实现通用的代码。比如Person有个Start属性, Car也有个Start属性,有个功能是需要为由Start的东西,显示的时候,都要带个星星的图标,这个时候,使用dynamic,就能够写出同时支持Person和Car的方法。

4. 使用Exposed

使用dynamic不能访问私有成员的问题,在Exposed里得到完全解决,从名字(翻译成暴露)也能看出来,它就是干这个的。

var exposedObj = Exposed.From(p);
Console.WriteLine(exposedObj.Name);
Console.WriteLine(exposedObj._age);
Console.WriteLine(exposedObj.GuessAge(20));

Exposed是第三方开源的,项目地址是https://github.com/Cognifide/ExposedObject,也可以在nuget中下载到。

5. 大杀器Clay

看到上面的“废话”,动态语言的爱好者只会冷笑一下,丑陋的静态编译语言,这些东西在动态语言里面,“这都不是事”。好吧,我承认,但是看完了Clay,也许能改变你的看法。

dynamic New = new ClayFactory();
var person = New.Person().Name("Louis")._age(30);
person.GuessAge = new Func<int, bool>(x => x == person._age);
Console.WriteLine(person.Name);
Console.WriteLine(person._age);
Console.WriteLine(person.GuessAge()(20));

跟多的了解Clay,可以看这篇http://www.cnblogs.com/JustRun1983/p/3529157.html

转载于:https://www.cnblogs.com/JustRun1983/p/3830764.html

代替Reflection(反射)的一些方法相关推荐

  1. Java反射机制的基本概念与使用_Java进阶之reflection(反射机制)——反射概念与基础...

    反射机制是Java动态性之一,而说到动态性首先得了解动态语言.那么何为动态语言? 一.动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见 ...

  2. java 反射 set方法_java 反射调用set方法

    Java语言中的许多库类名称,多与咖啡有关.下面是小编为您带来的java 反射调用set方法,希望对大家有所帮助. java 反射调用set方法: import java.beans.Property ...

  3. java 反射 对象的方法_java通过反射创建对象并调用方法

    这篇文章主要介绍了java通过反射创建对象并调用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.用户类 package com.lf.ent ...

  4. java反射 数组类,乐字节Java反射之三:方法、数组、类加载器和类的生命周期

    继续讲述Java反射之三:方法.数组.类加载器 一.方法 获取所有方法(包括父类或接口),使用Method即可. public static void test() throwsException { ...

  5. JUnit 3.8 通过反射测试私有方法

    测试私有(private)的方法有两种: 1)把目标类的私有方法(修饰符:private)修改为(public),不推荐,因为修改了源程序不佳 2)通过反射 (推荐) 代码演示: 目标程序 Priva ...

  6. python_day21面向对象的进阶(反射,内置方法,)

    # 两个内置函数 *# 反射 *****# 内置方法 *** # 类(定义) # 静态属性 类属性(变量) 直接写在类中,全大写 # 动态属性 方法(函数) self # 类方法 @classmeth ...

  7. java 反射 调用私有构造函数_使用反射调用私有方法

    1.创建一个被调用的类 /** * @version 1.0 * @Author F-llin * @Date 2020-12-04 13:53 */ public class Bean{ priva ...

  8. C# 知识点笔记:IEnumerable的使用,利用反射动态调用方法

    IEnumerable<T>的使用 创建一个IEnumerable对象 List<string> fruits = new List<string> { " ...

  9. Python面向对象06/反射/双下方法

    目录 day 26 /反射,双下方法 目录 1.元类type 2.反射 3.函数与类的区别 4.特殊的双下方法 day 26 /反射,双下方法 目录 1.元类type type:获取对象从属的类Pyt ...

最新文章

  1. tensorflow的tf.reduce_mean函数
  2. 【数据挖掘】数据挖掘算法 组件化思想 ( 模型或模式结构 | 数据挖掘任务 | 评分函数 | 搜索和优化算法 | 数据管理策略 )
  3. 表中的数据导出为insert语句的简单方法
  4. 用隐马尔可夫模型(HMM)做命名实体识别——NER系列(二)
  5. Mac更新VSCode写权限被拒绝 Cannot update while running on a read-only volume
  6. sqlldr 导入乱码,Oracle客户端字符集问题
  7. 【转】Azure 命令行工具大混战,都是什么,该选哪个?
  8. 1.10 编程基础之简单排序 10 单词排序 python
  9. 使用React Router v4的嵌套路由
  10. numpy序列预处理dna序列_干货 :教你一文掌握数据预处理
  11. spss正态性检验_SPSS和R中的正态分布的确定和几何均值的计算
  12. 发生了未经处理的异常
  13. 梓论坛 zibbs 1.0 发布,PHP 轻论坛系统
  14. java生成有理数_JAVA程序设计-有理数类的设计
  15. python爬取腾讯vip_用Python批量爬取付费vip数据,竟然如此简单
  16. ONLYOFFICE历史版本开发技术之二
  17. 【高等数学】去心邻域与邻域的意义
  18. Unity 3D做2D坦克大战--敌人自动攻击AI编写
  19. Zotero+onedrive同步问题
  20. Tuxera NTFS Mac2022mac写入ntfs移动硬盘插件

热门文章

  1. CUDA TOOlkit Programming Guide K. Unified Memory Programming
  2. java Spring beans
  3. java 类变量方法实例对象方法
  4. 2.6 谷歌 Inception 网络简介
  5. oracle在linux上使用裸设备,在linux下构建基于LVM的裸设备数据库
  6. 9600kf功耗和温度评测_谁更受主流消费者青睐:AMD锐龙5 3500X对比英特尔酷睿i5-9600KF...
  7. VMware-vRealize-Log-Insight-8.2.0.0安装部署指南
  8. 2019云计算战局前瞻:百度云要啃“硬骨头”
  9. Spring Boot学习总结(6)——SpringBoot解决ajax跨域请求问题的配置
  10. 大型网站技术架构(三)架构核心要素