2反射基本使用一
反射
就是操作dll文件的一个类库,dll文件和类库是一个东西。
一般项目的bin文件夹下面的Debug文件夹下面都会自动生成几个文件,其中就有.exe为后缀名的文件,一般类库的bin文件夹下面的Debug文件夹下面会有一个 .dll 结尾的后缀名的文件,这都叫程序集,即使删除这个文件里的文件,再次生成编译系统也会帮我们创建。
使用
1,查找(加载)DLL文件,加载程序集
2,通过Reflection反射类库里的各种方法来操作dll文件。通过程序集来获取里面的类。
使用反射进行普通类和普通方法的调用
利用反射创建dll里的指定类的对象
//【1】加载dll文件,获取程序集
//加载一个dll文件存在一个程序集对象里,Assembly表示一个程序集类,用来装加载的dll文件,
////方式1
//Assembly assembly = Assembly.Load("SqlServerDB");//这种方式要将需要加载的dll文件复制到当前项目的启动项目下(也就是bin\Debug\),也可以直接添加对应的dll项目引用,这样就不用手动复制了,它会自动复制
//方式2,使用完整路径,这种就可以不添加引用
Assembly assembly = Assembly.LoadFile(@"C:\Users\Admin\Desktop\TestConsoleApp1\SqlServerDB\bin\Debug\SqlServerDB.dll");
//【2】获取指定类,通过程序集获取类
Type type = assembly.GetType("SqlServerDB.ReflictionTest");
////【3】实例化
//Class class=new Class();//这种实例化方式是知道具体类型的实例化,是静态的实例化
//实例化类,实例化的时候调用无参构造函数
object obj = Activator.CreateInstance(type);//动态的实例化,可以不用知道类型,不过这样只会调用无参构造函数
////实例化类,实例化的时候调用有参构造函数
//object obj = Activator.CreateInstance(type, new object[] { "FHZM" });
////实例化私有类,私有类,就是将默认的无参构造函数改为private,这样就没法实例化了,这样为了类的安全,不想被调用,但是可以通过自己安排的方式调用,比如在其它方法里使用反射来调用
//object obj = Activator.CreateInstance(type, true);
利用反射找出dll(类库)里面的所有类
//【1】加载dll文件
Assembly assembly = Assembly.LoadFile(@"C:\Users\Admin\Desktop\TestConsoleApp1\SqlServerDB\bin\Debug\SqlServerDB.dll");
////【2】获取dll里的所有类
Type[] type = assembly.GetTypes();
foreach (var item in type)
{
Console.WriteLine(item.Name);//输出所有的类名,用Name属性
}
利用反射找出dll里面的指定类的所有构造函数,以及构造函数里面的参数
//【1】加载dll文件
Assembly assembly = Assembly.LoadFile(@"C:\Users\Admin\Desktop\TestConsoleApp1\SqlServerDB\bin\Debug\SqlServerDB.dll");
//【2】获取dll里的指定类
Type type = assembly.GetType("SqlServerDB.ReflictionTest");
//【2】获取类里的所有构造函数
//通过BindingFlags.Instance | BindingFlags.NonPublic可以找到私有的构造方法,
//不加的话私有的构造方法找不到,加了的话只能找到私有的构造函数,如果需要公有的和私有的同时找,就要再在后面加一个| BindingFlags.Public
ConstructorInfo[] constructorInfos = type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
//获取每个构造函数的参数
//循环所有构造函数
foreach (ConstructorInfo cotr in constructorInfos)
{
Console.WriteLine("\n\n构造方法:" + cotr);//只显示方法名:cotr.Name
//循环输出每个构造函数里的参数
foreach (var param in cotr.GetParameters())
{
Console.WriteLine("参数名:" + param.Name + " ,参数类型:" + param.ParameterType);//输出所有构造函数的名字,用Name属性获取构造函数的名字
}
}
调用类的公共方法
//加载程序集
Assembly assembly = Assembly.LoadFile(@"C:\Users\Admin\Desktop\TestConsoleApp1\SqlServerDB\bin\Debug\SqlServerDB.dll");
//获得指定类的类型
Type type = assembly.GetType("SqlServerDB.ReflictionTest");
//调用构造函数,实例化一个该类的对象
object obj = Activator.CreateInstance(type, new object[] { "张三" });//加true表示实例化私有类,但是只能调用私有的无参构造函数,
//从该类里获取指定方法
var method = type.GetMethod("Show1");
//通过该类对象调用,如果没参数也要加new object[] { },有参数则直接把实参写在里面即可:如:object[] {"参数1" }
method.Invoke(obj, new object[] { });
调用类的私有方法
//加载程序集
Assembly assembly = Assembly.LoadFile(@"C:\Users\Admin\Desktop\TestConsoleApp1\SqlServerDB\bin\Debug\SqlServerDB.dll");
//获得指定类的类型
Type type = assembly.GetType("SqlServerDB.ReflictionTest");
//调用构造函数,实例化一个该类对象
object obj = Activator.CreateInstance(type, new object[] { "张三" });//加true表示实例化私有类,但是只能调用私有的无参构造函数,
//从该类里获取指定方法
var method = type.GetMethod("Show2", BindingFlags.Instance | BindingFlags.NonPublic);//BindingFlags.Instance | BindingFlags.NonPublic表示找私有的方法
//调用,如果没参数也要加new object[] { },有参数则直接把实参写在里面即可:如:object[] {"参数1" }
method.Invoke(obj, new object[] { });
调用指定类的泛型方法
//加载程序集
Assembly assembly = Assembly.LoadFile(@"C:\Users\Admin\Desktop\TestConsoleApp1\SqlServerDB\bin\Debug\SqlServerDB.dll");
//获得指定类的类型
Type type = assembly.GetType("SqlServerDB.ReflictionTest");
//调用构造函数,实例化一个对象
object obj = Activator.CreateInstance(type, new object[] { "张三" });//加true表示实例化私有类,但是只能调用私有的无参构造函数,
var method = type.GetMethod("tTest");//查找指定方法
var genericMethod = method.MakeGenericMethod(new Type[] { typeof(int) });//指定泛型参数类型T
//如果有参数在后面写即可,如:new object[] { 55,66 }
genericMethod.Invoke(obj, new object[] { });//调用
使用反射实例化泛型类和泛型方法的调用
//加载程序集
Assembly assembly = Assembly.LoadFile(@"C:\Users\Admin\Desktop\TestConsoleApp1\SqlServerDB\bin\Debug\SqlServerDB.dll");
//获得指定类的类型,泛型类在获取时候,“ `n ”表示泛型类需要指定的泛型参数个数,比如`2表示需要指定两个类型给它
Type type = assembly.GetType("SqlServerDB.GenericClass`2");
//指定该泛型类的参数类型
type = type.MakeGenericType(typeof(int), typeof(string));
//调用构造函数,实例化一个泛型对象
object obj = Activator.CreateInstance(type);
//拿到方法
var method = type.GetMethod("GenericMethod");
//指定该泛型方法的参数类型
method = method.MakeGenericMethod(typeof(int));
//调用,如果是调用有参数的,直接在后面写参数即可,如: new object[] {555 }
method.Invoke(obj, new object[] { });
获取和设置属性值
//加载程序集
Assembly assembly = Assembly.LoadFile(@"C:\Users\Admin\Desktop\TestConsoleApp1\SqlServerDB\bin\Debug\SqlServerDB.dll");
//获得指定类的类型
Type type = assembly.GetType("SqlServerDB.PropertyClass");
//获取该类的全部属性
PropertyInfo[] properties = type.GetProperties();
//循环输出属性名
foreach (var propert in properties)
{
Console.WriteLine(propert.Name);
}
//创建一个该类的对象obj
object obj = Activator.CreateInstance(type);
//循环所有属性并给obj对象的属性设置值,并且输出obj对象对应的属性的值
foreach (var propert in properties)
{
if (propert.Name.Equals("Name"))
{
//设置属性值
propert.SetValue(obj, "张三");
}
else if (propert.Name.Equals("Age"))
{
//设置属性值
propert.SetValue(obj, 18);
}
else if (propert.Name.Equals("Sex"))
{
//设置属性值
propert.SetValue(obj, '女');
}
//输出obj对象的属性对应的值
Console.WriteLine(propert.GetValue(obj));
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构