c#中反射
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | 在.Net 中,程序集(Assembly)中保存了元数据(MetaData)信息,因此就可以通过分析元数据来获取程序集中的内容,比如类,方法,属性等,这大大方便了在运行时去动态创建实例。 MSDN解释如下: 反射提供了封装程序集、模块和类型的对象(Type 类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了属性,可以利用反射对它们进行访问。 主要用途: 动态加载DLL,实现插件机制。 实例化DLL中的类型。 执行后期绑定,访问在运行时创建的类型的方法。 今天我就介绍下后面的两个用途,其实最初的目的只是想根据配置文件中的值创建对应对象。 Dll 先上一段代码,这是要调用的ClassGreenerycn类,它被编译为DllDemo.dll。 using System; namespace DllDemo { public class ClassGreenerycn { public string Name { get ; set ; } public bool IsTest { get ; set ; } public void Hello() { Console.WriteLine(Name); } } } 很简单的代码,就是一个类中有两个属性,Hello方法会向命令行中输出Name的名称。 使用反射创建Dll中的类实例并调用方法 现在再新建一个命令行的工程,该工程就一个用途,动态加载DllDemo.dll,然后实例化一个Name为Greenerycn,IsTest为True的对象,并调用Hello方法。 详细步骤如下: 1.引用反射的命名空间: using System.Reflection; 2.动态加载Dll 动态加载Dll有3个函数: public static Assembly Load( string assemblyString); 该方法传入的是Dll的名字,该Dll必须位于全局缓存GAC中才行,不然会报“System.IO.FileLoadException: 未能加载文件或程序集”的异常。 public static Assembly LoadFile( string path); 这个LoadFile最方便,参数就是dll的路径。 public static Assembly LoadFrom( string assemblyFile); 这个方法也可以,参数同样是dll路径。 3.获取ClassGreenerycn类的类型 var type = asm.GetType( "DllDemo.ClassGreenerycn" ); 注意,这里需要完整的类型名称,包括签名的命名空间。 4.创建该类型的实例 var instance = asm.CreateInstance( "DllDemo.ClassGreenerycn" ); 5.设置属性 type.GetProperty( "Name" ).SetValue(instance, "http://greenerycn.cnblogs.com" , null ); type.GetProperty( "IsTest" ).SetValue(instance, true , null ); 6.获取Hello方法 var method = type.GetMethod( "Hello" ); 7.调用Hello方法 method.Invoke(instance, null ); 8.编译运行 reflaction_demo 完整的代码 using System.Reflection; namespace ReflectionDllDemo { class Program { static void Main( string [] args) { var asm = Assembly.LoadFile( @"d:\3_code\DotNet\DllDemo\DllDemo\bin\Debug\DllDemo.dll" ); var type = asm.GetType( "DllDemo.ClassGreenerycn" ); var instance = asm.CreateInstance( "DllDemo.ClassGreenerycn" ); type.GetProperty( "Name" ).SetValue(instance, "http://greenerycn.cnblogs.com" , null ); type.GetProperty( "IsTest" ).SetValue(instance, true , null ); var method = type.GetMethod( "Hello" ); method.Invoke(instance, null ); } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通