.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.信号与信号之间 ...
随机推荐
- C#对象与XMl文件之间的相互转换
C#提供三种序列化方式,分别为: 1.是使用BinaryFormatter进行串行化: 2.使用SoapFormatter进行串行化: 3.使用XmlSerializer进行串行化.其中对于Binar ...
- ios基础之入门(一)
最近找到了一个可以接触ios开发的职位,可以系统的学习和练习了.先从最基本的开始: 一.获取控件的两种方式 1)第一种,也是经常使用的一种,通过IBOutlet方式.直接按住control键,将控件和 ...
- 6/20 sprint3 看板和燃尽图的更新
- 数论 - 素数的运用 --- poj 2689 : Prime Distance
Prime Distance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12512 Accepted: 3340 D ...
- C#写文本日志帮助类(支持多线程)
代码: using System; using System.Configuration; using System.IO; using System.Threading.Tasks; namespa ...
- EasyUI组合树插件
一.引用CSS和JS <link href="~js/easyui/easyui.css" rel="stylesheet" type="tex ...
- 从web页面启动winform程序的实现方法
本文实现的需求是: A.通过web页面启动winform程序: B.将页面的参数传递给winform程序: C.winform程序已经启动并正在运行时,从web页面不能重新启动winform程序,只是 ...
- asp.net 前台绑定后台变量方法总结:<%= %> 和<%# %>的区别
经常会碰到在前台代码中要使用(或绑定)后台代码中变量值的问题.一般有<%= str%>和<%# str %>两种方式,这里简单总结一下.如有错误或异议之处,敬请各位指教. 一 ...
- WebGL/X3DOM 跑在 iOS
iOS是最早支持WebGL的移动操作系统之一,我们一直在努力让X3DOM运行在那些设备上.然而,标准的Safari浏览器默认是没有开启的.这种情况从iOS8发生改变,iOS8现在完全支持WebGL - ...
- 防止用户误操作退出APP的处理
/** * 软件退出的处理:先跳到第一个页面,再点提示“再点一次退出”,2秒内再点一次退出 * 防止用户误操作 */ private boolean isExist=false; private Ha ...