博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.NET 反射的使用
阅读量:6536 次
发布时间:2019-06-24

本文共 3857 字,大约阅读时间需要 12 分钟。

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.根据实例和其属性名(字符串) 获取该属性

/// /// 获取某个对象的某个属性值/// /// 对象/// 属性名/// 
属性值
private string GetPropertyValue
(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 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动态编译的文章

关于应用程序域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();

相关文章


 

 

 

 

转载于:https://www.cnblogs.com/TiestoRay/p/2605485.html

你可能感兴趣的文章
The Packaging Process in Yocto/OE
查看>>
golang--Redis最佳的Go语言驱动
查看>>
JQUERY 对 表格中的数据重排序
查看>>
Java中的finalize()
查看>>
程序员常用借口指南
查看>>
关于PXE网络安装linux系统中碰到的个别问题
查看>>
storm笔记一
查看>>
awk 常用方法
查看>>
Android网络框架实现之【Retrofit+RxJava】
查看>>
Android文件的加密与解密
查看>>
Ubuntu查看目录树形结构
查看>>
OSChina 周二乱弹 ——人和人之间的关系用通话时间来表述
查看>>
OSChina 周六乱弹 ——通常他们这么修复的bug,我都接受不了
查看>>
Log4j 2使用教程
查看>>
SOAP webserivce 和 RESTful webservice 对比及区别
查看>>
安装apache
查看>>
JavaScript中DOM基础
查看>>
完全配置Python3+PyQt5+Eric6开发环境
查看>>
做产品的一些思考
查看>>
Cookie编程问题及Base64中文编码问题
查看>>