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);
        }
    }
}

 

posted @   甜菜波波  阅读(208)  评论(0编辑  收藏  举报
编辑推荐:
· 基于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最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示