本文只介绍使用方式,不介绍理论基础。理论和详细教程请直接看官网
测试类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
namespace SqlDB
{
public class ReflectionTest
{
private ReflectionTest()
{
WriteLine("这是私有无参构造方法");
}
//public reflectiontest()
//{
// writeline("这是无参构造方法");
//}
public ReflectionTest(string name)
{
WriteLine($"一个参数构造方法值是:{name}");
}
public void show()
{
WriteLine("公共方法");
}
private void show1()
{
WriteLine("私有方法");
}
public void show2<T>()
{
WriteLine("无参泛型方法");
}
public void show3<T>(string name ,int age )
{
WriteLine("有参泛型方法" + name + age + "");
}
}
}
一、通过Assembly拿到对应的程序集
static void Main(string[] args)
{
//[1]加载Dll
//获取程序集Dll 方式1 获取启动目录下的sqlDB.dll 也可以通过引用的方式加载,然后获取
//Assembly assembly = Assembly.Load("SqlDB");
//方式2 绝对路径
//Assembly assembly1 = Assembly.LoadFile(@"G:\云盘 .net 项目\Cshap反射\Cshap反射\bin\Debug\net5.0\SqlDB.dll");
//方式3 包含前2种加载方式。一般用这种
Assembly assembly2 = Assembly.LoadFrom("sqlDB.dll");
Write(assembly2.FullName);
ReadKey();
}
二、获取指定类型并实例化
//[2]获取指定类型
//默认情况下 你是不知道dll中有哪些内容,可以通过反射获取,这里我默认是知道我dll有哪些东西的。
//获取dll下的ReflectionTest类
Type type = assembly2.GetType("SqlDB.ReflectionTest");
//【3】实例化该类型
//ReflectionTest reflectionTest = new ReflectionTest();这种一般是态实例化
//动态实例化
// var reflectionClass = Activator.CreateInstance(type);//动态创建
//带参数的动态实例化
var reflectionParameter = Activator.CreateInstance(type,new object[] { "反射学习"});
//具体的可以自行查阅Activator这个类,提供了很多静态方法,和重载,可以F1官网查看。一般的上面2个已经够用了。
//调用私有无参构造函数
var reflectionClass = Activator.CreateInstance(type,true);
三、获取dll里面的所有类型构造函数和参数。
//获取所有类型
foreach (var Titem in assembly2.GetTypes())
{
//获取所有的类名称
WriteLine(Titem.Name);
//获取类中的所有构造函数 //枚举中的按位与和或 就是找到指定的枚举值 有就返回,没有就累加 累加后有匹配的就返回 具体网上百度
foreach (var crot in Titem.GetConstructors(BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance))
{
//打印出构造函数名称
WriteLine(crot.Name);
//打印对应的构造参数
foreach (var item in crot.GetParameters())
{
WriteLine($"类型{item.ParameterType}名称 {item.Name}");
}
}
}
四、获取类型中的方法和方法调用
//获取该类型下的所有方法。
var allMethods = type.GetMethods(BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.Public);
foreach (var Method in allMethods)
{
//打印该类型下的所有公共方法和私有方法的名称
WriteLine(Method.Name);
}
WriteLine("-----------------------------------------------------------");
//调用无参方法
var Method1 = type.GetMethod("show");
Method1.Invoke(reflectionClass, new object[] { });
//调用私有
var Method2 = type.GetMethod("show1",BindingFlags.NonPublic|BindingFlags.Instance);
Method2.Invoke(reflectionClass, new object[] { });
//调用泛型方法
var Method3 = type.GetMethod("show2");
var GenericMethod = Method3.MakeGenericMethod(new Type[] { typeof(int) });
GenericMethod.Invoke(reflectionClass, new object[] { });
//调用有参泛型
var Method4 = type.GetMethod("show3");
var GenericMethod4 = Method4.MakeGenericMethod(new Type[] { typeof(int) });
//reflectionClass 是你动态实例化的对象
GenericMethod4.Invoke(reflectionClass, new object[] { "小王",18});
五、调用泛型类和泛型方法
测试类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SqlDB
{
public class GenericClass<T,W>
{
public void GenericMethod<TType>()
{
Console.WriteLine("泛型类+泛型方法");
}
}
}
操作代码:
Assembly assembly2 = Assembly.LoadFrom("sqlDB.dll");
Type type = assembly2.GetType("SqlDB.GenericClass`2").MakeGenericType(new Type[] { typeof(string),typeof(int)});
var newclass = Activator.CreateInstance(type);
var method = type.GetMethod("GenericMethod").MakeGenericMethod(typeof(int));
method.Invoke(newclass,new object[] { });
其中泛型类的结构可以通过反编译工具如:ILSPY去看泛型类的结构,GenericClass<T,W>反编译的结构就是GenericClass `2 其中 ``2 表示的就是该泛型类有2个类型参数。
六、给属性设值和获取值
Assembly assembly = Assembly.LoadFrom("sqlDB.dll");
Type type = assembly.GetType("SqlDB.Propertyclass");
var obj = Activator.CreateInstance(type);
foreach (var prop in type.GetProperties())
{
//打印所有的属性名称
Console.WriteLine(prop.Name);
//给属性设置值
if (prop.Name.Equals("ID"))
{
prop.SetValue(obj, 1);
}
else if (prop.Name.Equals("name"))
{
prop.SetValue(obj, "小王");
} else if (prop.Name.Equals("despaction"))
{
prop.SetValue(obj, "反射");
}
Console.WriteLine(prop.GetValue(obj));
}