.NET 反射的使用
1.根据类名获取类实例
- string className = "Company.BigProgram.BLL.TestClass";
- Type type = Type.GetType(className);
- if (type != null)
- {
- Object obj = Activator.CreateInstance(type);
- bool b = obj is TestClass;
- }
className是包含命名空间的类名
在这里只是根据类名创建了一个实例,但是没有将其转换为相应的实体类。所以一般情况 这里反射的类都应该有一个共同的接口(或者说有一个共同的父类);
这样就能很明确的创建和使用由反射得来的实体类了
- //接口
- namespace Company.BigProgram.BLL
- {
- public interface ITest
- {
- void say(string name);
- }
- }
- //具体实现类
- namespace Company.BigProgram.BLL
- {
- public class TestClass:ITest
- {
- public void say(string name)
- {
- Console.WriteLine("看这里");
- }
- }
- }
- //结果输出
- string className = "ImageTest.TestClass";
- Type type = Type.GetType(className);
- if (type != null)
- {
- ITest obj = Activator.CreateInstance(type) as ITest;
- bool b = obj is TestClass;
- MessageBox.Show(b.ToString());//True
- }
2.根据实例和其属性名(字符串) 获取该属性
- /// <summary>
- /// 获取某个对象的某个属性值
- /// </summary>
- /// <param name="type">对象</param>
- /// <param name="propName">属性名</param>
- /// <returns>属性值</returns>
- private string GetPropertyValue<T>(T item, string propName)
- {
- Type type = item.GetType();//获取类型
- System.Reflection.PropertyInfo propertyInfo = type.GetProperty(propName);
- return (propertyInfo.GetValue(item, null) ?? "").ToString();
- }
3.根据实例和其方法名(字符串)获取该方法并调用
- private void GetPropertyValue<T>(T item, string name,object[] paras)
- {
- System.Type type = item.GetType();//获取类型
- System.Reflection.MethodInfo func = type.GetMethod(name);//获取方法
- func.Invoke(item, paras);//调用 item是调用该方法的对象,paras是参数
- }
- private class Person
- {
- public void say()
- {
- MessageBox.Show("XXXXOOOO");
- }
- public void call(string content)
- {
- MessageBox.Show(content);
- }
- }
上面三种Demo都是针对提前定义好的类型和方法属性。
下面是根据提供的字段信息动态编译的方法。
- string colsStr = "Age,Name,Sex,Birthday";//字段名
- string[] colNames = colsStr.Split(',');
- string clsName = "DynUserTable";//动态生成的类名
- string ns = "MyWeb.Test";//命名空间
- var propStr = "";
- foreach (var c in colNames)
- {
- propStr += $" public string {c}{{set;get;}}\r\n";
- }
- var typeStr = $@"
- namespace {ns}
- {{
- public class {ns} {{ {propStr} }}
- }}";//拼接类的定义内容
- //获取编译结果
- var cr = new CSharpCodeProvider()
- .CompileAssemblyFromSource(new CompilerParameters(new string[] { "System.dll" }), typeStr);
- //获取类型
- var targetType = cr.CompiledAssembly.GetType($"{ns}.{clsName}");
这里有一篇.NET动态编译的文章.NET中的动态编译
关于应用程序域AppDomain的使用 走近.NET AppDomain
说到动态编译 Emit效率更高,是通过C#直接生成IL,不过可读性较差
- //动态创建程序集
- AssemblyName DemoName = new AssemblyName("DynamicAssembly");
- AssemblyBuilder dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(DemoName
- , AssemblyBuilderAccess.ReflectionOnly);//如果需要持久化程序集 则选择RunAndSave或Save
- //动态创建模块
- ModuleBuilder mb = dynamicAssembly.DefineDynamicModule(DemoName.Name, DemoName.Name + ".dll");
- //动态创建类MyClass
- TypeBuilder tb = mb.DefineType("MyClass", TypeAttributes.Public);
- //动态创建字段
- FieldBuilder fb = tb.DefineField("myField", typeof(string), FieldAttributes.Private);
- //动态创建构造函数(一个参数)
- Type[] clorType = new Type[] { typeof(string) };
- ConstructorBuilder cb1 = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, clorType);
- //生成 Microsoft 中间语言 (MSIL) 指令(将构造函数的参数赋给字段fb)
- ILGenerator ilg = cb1.GetILGenerator();
- ilg.Emit(OpCodes.Ldarg_0);
- ilg.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
- ilg.Emit(OpCodes.Ldarg_0);
- ilg.Emit(OpCodes.Ldarg_1);
- ilg.Emit(OpCodes.Stfld, fb);
- ilg.Emit(OpCodes.Ret);
- //动态创建属性
- PropertyBuilder pb = tb.DefineProperty("MyProperty", PropertyAttributes.HasDefault, typeof(string), null);
- //动态创建方法
- MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName;
- MethodBuilder myMethod = tb.DefineMethod("get_Field", getSetAttr, typeof(string), Type.EmptyTypes);
- //生成指令(方法返回fb)
- ILGenerator numberGetIL = myMethod.GetILGenerator();
- numberGetIL.Emit(OpCodes.Ldarg_0);
- numberGetIL.Emit(OpCodes.Ldfld, fb);
- numberGetIL.Emit(OpCodes.Ret);
- //使用动态类创建类型
- Type classType = tb.CreateType();
相关文章
.NET 反射的使用的更多相关文章
- 隐私泄露杀手锏 —— Flash 权限反射
[简版:http://weibo.com/p/1001603881940380956046] 前言 一直以为该风险早已被重视,但最近无意中发现,仍有不少网站存在该缺陷,其中不乏一些常用的邮箱.社交网站 ...
- Java学习之反射机制及应用场景
前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框 ...
- 关于 CSS 反射倒影的研究思考
原文地址:https://css-tricks.com/state-css-reflections 译者:nzbin 友情提示:由于演示 demo 的兼容性,推荐火狐浏览.该文章篇幅较长,内容庞杂,有 ...
- 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)
建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...
- 运用Mono.Cecil 反射读取.NET程序集元数据
CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...
- .NET面试题系列[6] - 反射
反射 - 定义,实例与优化 在面试中,通常会考察反射的定义(操作元数据),可以用反射做什么(获得程序集及其各个部件),反射有什么使用场景(ORM,序列化,反序列化,值类型比较等).如果答得好,还可能会 ...
- .NET基础拾遗(4)委托、事件、反射与特性
Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...
- C++的性能C#的产能?! - .Net Native 系列五:.Net Native与反射
此系列系小九的学堂原创翻译,翻译自微软官方开发向导,一共分为六个主题.本文是第五个主题:.Net Native与反射. 向导文链接:<C++的性能C#的产能?! - .Net Native 系列 ...
- [源码]Literacy 快速反射读写对象属性,字段
Literacy 说明 Literacy使用IL指令生成方法委托,性能方面,在调用次数达到一定量的时候比反射高很多 当然,用IL指令生成一个方法也是有时间消耗的,所以在只使用一次或少数几次的情况,不但 ...
- SI与EMI(一) - 反射是怎样影响EMI
Mark为期两天的EMC培训中大概分成四个时间差不多的部分,简单来说分别是SI.PI.回流.屏蔽.而在信号完整性的书籍中,也会把信号完整性分为:1.信号自身传输的问题(反射,损耗):2.信号与信号之间 ...
随机推荐
- ASP.NET 图片上传工具类 upload image简单好用功能齐全
使用方法: UploadImage ui = new UploadImage(); /***可选参数***/ ui.SetWordWater = "哈哈";//文字水印 // ui ...
- Sprint第三个冲刺(第七天)
项目基本上可以说完成了,只是还有些小bug要修复.
- Winform里面的缓存使用
缓存在很多情况下需要用到,合理利用缓存可以一方面可以提高程序的响应速度,同时可以减少对特定资源访问的压力.本文主要针对自己在Winform方面的缓存使用做一个引导性的介绍,希望大家能够从中了解一些缓存 ...
- 新增的querySelector、querySelectorAll测试
从IE9开始DOM开始支持支持CSS的选择器了,DOM提供了两个接口 querySelector 得到一个DOM querySelectorAll 得到一组DOM 一个个的解释这些选择器也没有必要,我 ...
- 【Unity】13.3 Realtime GI示例
分类:Unity.C#.VS2015 创建日期:2016-04-19 一.简介 使用简单示例而不是使用实际示例的好处是能让你快速理解光照贴图和光影效果相关的概念和基本设置办法,这样可避免实际复杂场景中 ...
- 开源的javascript实现页面打印功能,兼容所有的浏览器(情况属实)
这篇文章完全是属于技术文章,也是记录一下自己在项目当中遇到的坑爹问题啊,因为是B/S的程序,所以打印功能还是必须要有的,对于打印我选择了一个js插件,发现非常的简单和方便,所以这里拿出来和大家分享一下 ...
- csharp: Export DataSet into Excel and import all the Excel sheets to DataSet
/// <summary> /// Export DataSet into Excel /// </summary> /// <param name="send ...
- NLog在.NET Core Console Apps中的简单应用
什么是NLog? NLog is a free logging platform for .NET with rich log routing and management capabilities. ...
- mysql grant all on *.* to xxx@'%' 报Access denied for user 'root'@'localhost'
今日,开发反馈某台mysql服务器无法登陆,解决之后,远程登录后发现用户只能看到information_schema,其他均看不到. 故登录服务器执行: mysql> grant all on ...
- ES6新特性(函数默认参数,箭头函数)
ES6新特性之 函数参数的默认值写法 和 箭头函数. 1.函数参数的默认值 ES5中不能直接为函数的参数指定默认值,只能通过以下的变通方式: 从上面的代码可以看出存在一个问题,当传入的参数为0或者 ...