.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.信号与信号之间 ...
随机推荐
- Sql [hierarchyid]类型如何动态插入层级数据
[hierarchyid] 是个不错的数据类型,能够方便的操作树型结构,网上找了很多资料没找到如何做到动态插入节点的例子,只好从MSDN认真看了下资料写出了一个DEMO CREATE TABLE Em ...
- DataBase --- Intellij IDEA 14.1.4使用Java连接SQL Server教程
Java连接数据库的方法大体分为两种:正向连接和反向连接.反向连接需要编译器提供相关的插件来支持,目前主流的java IDE都支持反向连接.这里主要对正向连接做一个经验总结. 一.数据库的配置 1.新 ...
- Javascript语法去控制Web控件的Enabled属性
Web控件当使用Enabled属性时,它生成html之后会变成了disabled了.我们为了能够在javascript去控制控件的禁用与启用,得从这个disabled入手.如:
- 【iOS】线程安全的文件读写
前段时间看了一遍GCD(Grand Central Dispatch)多线程,GCD是苹果为多核开发提供的解决方案 多线程最常见的问题就是读写,比如数据库读写,文件读写,读取是共享的,写是互斥,允许多 ...
- 新增的querySelector、querySelectorAll测试
从IE9开始DOM开始支持支持CSS的选择器了,DOM提供了两个接口 querySelector 得到一个DOM querySelectorAll 得到一组DOM 一个个的解释这些选择器也没有必要,我 ...
- [WCF实践]1.WCF使用net.tcp寄宿到IIS中
一.IIS部分 环境:Windows Server 2008 R2 1.安装WAS,如下图所示: 2.网站net.tcp协议绑定,如下图所示: 3.网站启用net.tcp,如下图所示: 二 ...
- Python入门笔记(16):对文件的操作(2)
一.文件系统 从系统角度来看,文件系统是对文件存储器空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统.具体地说,它负责为用户建立文件,存入.读出.修改.转储文件,控制文件的存取,当用 ...
- sql server聚合函数sum计算出来为空,怎样返回0
通常我们计算数据库中表的数据有几个常用的聚合函数 1.count : 计数 2.sum: 计算总和 3.avg: 取平均值 4.max: 取最大值 5.min: 取最小值 6.isnull: 当返回数 ...
- Fluent NHibernate other example
测试用的当前最新版本: sql: --- CREATE TABLE Users ( UserID INT IDENTITY(1,1) PRIMARY KEY, [Name] VARCHAR(50) N ...
- PHP学习笔记:使用session来存储用户的登录信息
session可以用来存储多种类型的数据,因此具有很多的用途,常用来存储用户的登录信息,购物车数据,或者一些临时使用的暂存数据等. 用户在登录成功以后,通常可以将用户的信息存储在session中,一般 ...