代替Reflection(反射)的一些方法
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(反射)的一些方法相关推荐
- Java反射机制的基本概念与使用_Java进阶之reflection(反射机制)——反射概念与基础...
反射机制是Java动态性之一,而说到动态性首先得了解动态语言.那么何为动态语言? 一.动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的变化.比如常见 ...
- java 反射 set方法_java 反射调用set方法
Java语言中的许多库类名称,多与咖啡有关.下面是小编为您带来的java 反射调用set方法,希望对大家有所帮助. java 反射调用set方法: import java.beans.Property ...
- java 反射 对象的方法_java通过反射创建对象并调用方法
这篇文章主要介绍了java通过反射创建对象并调用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.用户类 package com.lf.ent ...
- java反射 数组类,乐字节Java反射之三:方法、数组、类加载器和类的生命周期
继续讲述Java反射之三:方法.数组.类加载器 一.方法 获取所有方法(包括父类或接口),使用Method即可. public static void test() throwsException { ...
- JUnit 3.8 通过反射测试私有方法
测试私有(private)的方法有两种: 1)把目标类的私有方法(修饰符:private)修改为(public),不推荐,因为修改了源程序不佳 2)通过反射 (推荐) 代码演示: 目标程序 Priva ...
- python_day21面向对象的进阶(反射,内置方法,)
# 两个内置函数 *# 反射 *****# 内置方法 *** # 类(定义) # 静态属性 类属性(变量) 直接写在类中,全大写 # 动态属性 方法(函数) self # 类方法 @classmeth ...
- java 反射 调用私有构造函数_使用反射调用私有方法
1.创建一个被调用的类 /** * @version 1.0 * @Author F-llin * @Date 2020-12-04 13:53 */ public class Bean{ priva ...
- C# 知识点笔记:IEnumerable的使用,利用反射动态调用方法
IEnumerable<T>的使用 创建一个IEnumerable对象 List<string> fruits = new List<string> { " ...
- Python面向对象06/反射/双下方法
目录 day 26 /反射,双下方法 目录 1.元类type 2.反射 3.函数与类的区别 4.特殊的双下方法 day 26 /反射,双下方法 目录 1.元类type type:获取对象从属的类Pyt ...
最新文章
- tensorflow的tf.reduce_mean函数
- 【数据挖掘】数据挖掘算法 组件化思想 ( 模型或模式结构 | 数据挖掘任务 | 评分函数 | 搜索和优化算法 | 数据管理策略 )
- 表中的数据导出为insert语句的简单方法
- 用隐马尔可夫模型(HMM)做命名实体识别——NER系列(二)
- Mac更新VSCode写权限被拒绝 Cannot update while running on a read-only volume
- sqlldr 导入乱码,Oracle客户端字符集问题
- 【转】Azure 命令行工具大混战,都是什么,该选哪个?
- 1.10 编程基础之简单排序 10 单词排序 python
- 使用React Router v4的嵌套路由
- numpy序列预处理dna序列_干货 :教你一文掌握数据预处理
- spss正态性检验_SPSS和R中的正态分布的确定和几何均值的计算
- 发生了未经处理的异常
- 梓论坛 zibbs 1.0 发布,PHP 轻论坛系统
- java生成有理数_JAVA程序设计-有理数类的设计
- python爬取腾讯vip_用Python批量爬取付费vip数据,竟然如此简单
- ONLYOFFICE历史版本开发技术之二
- 【高等数学】去心邻域与邻域的意义
- Unity 3D做2D坦克大战--敌人自动攻击AI编写
- Zotero+onedrive同步问题
- Tuxera NTFS Mac2022mac写入ntfs移动硬盘插件
热门文章
- CUDA TOOlkit Programming Guide K. Unified Memory Programming
- java Spring beans
- java 类变量方法实例对象方法
- 2.6 谷歌 Inception 网络简介
- oracle在linux上使用裸设备,在linux下构建基于LVM的裸设备数据库
- 9600kf功耗和温度评测_谁更受主流消费者青睐:AMD锐龙5 3500X对比英特尔酷睿i5-9600KF...
- VMware-vRealize-Log-Insight-8.2.0.0安装部署指南
- 2019云计算战局前瞻:百度云要啃“硬骨头”
- Spring Boot学习总结(6)——SpringBoot解决ajax跨域请求问题的配置
- 大型网站技术架构(三)架构核心要素