C# 利用反射根据类名创建类的实例对象
“反射”其实就是利用程序集的元数据信息。 反射可以有很多方法,编写程序时请先导入 System.Reflection 命名空间。
1、假设你要反射一个 DLL 中的类,并且没有引用它(即未知的类型):
Assembly assembly = Assembly.LoadFile("程序集路径,不能是相对路径"); // 加载程序集(EXE 或 DLL)
dynamic obj = assembly.CreateInstance("类的完全限定名(即包括命名空间)"); // 创建类的实例
2、若要反射当前项目中的类(即当前项目已经引用它了)可以为:
Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集
dynamic obj = assembly.CreateInstance("类的完全限定名(即包括命名空间)"); // 创建类的实例,返回为 object 类型,需要强制类型转换
3、也可以为:
Type type = Type.GetType("类的完全限定名");
dynamic obj = type.Assembly.CreateInstance(type);
4、不同程序集的话,则要装载调用,代码如下:
System.Reflection.Assembly.Load("程序集名称(不含文件后缀名)").CreateInstance("命名空间.类名", false);
如:
dynamic o = System.Reflection.Assembly.Load("MyDll").CreateInstance("MyNameSpace.A", false);
注意:由于要用到dynamic ,需要把target 改为4.0 ,如果编译时出现“找不到编译动态表达式所需的一个或多个类型。是否缺少引用?”的错误,是因为缺少一个引用,在项目里引用Miscorsoft.CSharp类库,添加后就能编译成功。
=======================================================
补充:
1)反射创建某个类的实例时,必须保证使用类的完全限定名(命名空间 + 类名)。Type.GetType 方法返回 null 则意味搜索元数据中的相关信息失败(反射失败),请确保反射时使用类的完全限定名。
2)反射功能十分强大,没有什么不能实现的。若实现“跨程序集”,请使用第一种方法创建类的实例,并反射该实例的字段、属性、方法、事件... 然后动态调用之。
/// <summary> /// 反射帮助类 /// </summary> public static class ReflectionHelper { /// <summary> /// 创建对象实例 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="fullName">命名空间.类型名</param> /// <param name="assemblyName">程序集</param> /// <returns></returns> public static T CreateInstance<T>(string fullName, string assemblyName) { string path = fullName + "," + assemblyName;//命名空间.类型名,程序集 Type o = Type.GetType(path);//加载类型 object obj = Activator.CreateInstance(o, true);//根据类型创建实例 return (T)obj;//类型转换并返回 } /// <summary> /// 创建对象实例 /// </summary> /// <typeparam name="T">要创建对象的类型</typeparam> /// <param name="assemblyName">类型所在程序集名称</param> /// <param name="nameSpace">类型所在命名空间</param> /// <param name="className">类型名</param> /// <returns></returns> public static T CreateInstance<T>(string assemblyName, string nameSpace, string className) { try { string fullName = nameSpace + "." + className;//命名空间.类型名 //此为第一种写法 object ect = Assembly.Load(assemblyName).CreateInstance(fullName);//加载程序集,创建程序集里面的 命名空间.类型名 实例 return (T)ect;//类型转换并返回 //下面是第二种写法 //string path = fullName + "," + assemblyName;//命名空间.类型名,程序集 //Type o = Type.GetType(path);//加载类型 //object obj = Activator.CreateInstance(o, true);//根据类型创建实例 //return (T)obj;//类型转换并返回 } catch { //发生异常,返回类型的默认值 return default(T); } } }
出处:https://www.cnblogs.com/feiyuhuo/p/5793606.html
关注我】。(●'◡'●)
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/10406834.html
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!
posted on 2019-02-20 15:19 jack_Meng 阅读(1046) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2017-02-20 WinForm设置窗体默认控件焦点
2017-02-20 C# winform窗口打开特效及窗口位置居中