反射
1.添加命名空间
using System.Reflection;
2.把dll加载入项目
Assembly ty = Assembly.Load("ClassLibraryTest");//不加dll后缀,在core里面使用容易报错 Assembly ty = Assembly.LoadFrom(@"E:\项目\ConsoleApp1\ClassLibraryTest\bin\Debug\net6.0\ClassLibraryTest.dll");//全路劲 Assembly ty = Assembly.LoadFrom("ClassLibraryTest.dll");//只要加后缀的dll Assembly ty = Assembly.LoadFile(@"E:\项目\ConsoleApp1\ClassLibraryTest\bin\Debug\net6.0\ClassLibraryTest.dll");//全路劲
3.调用方法
Type type = ty.GetType("ClassLibraryTest.Class1");//命名空间+类名
方法一:知道类型强制转换,再调用
Class1 objtype = Activator.CreateInstance(type, new object[] { "11111" }) as Class1;
objtype.Print();
方法二:动态类型 dynamic ,运行时直接调用
dynamic objtype= Activator.CreateInstance(type,"qqq"); //动态类型,运行时加载判断方法是否存在,不用强制转换
objtype.Print();
方法三:根据方法名直接调用 可调用 私有方法和静态方法
//MethodInfo? DoPrint= type.GetMethod("DoPrint", BindingFlags.NonPublic| BindingFlags.Instance); //调用private string DoPrint() NonPublic非公开方法,Instance必须要创建示例的方法
//DoPrint.Invoke(obj, null);
MethodInfo? print = type.GetMethod("Print" ,new Type[]{typeof(string)});//方法重载要把参数类型写上,不然要报错 System.Reflection.AmbiguousMatchException:“Ambiguous match found(方法:public void Print(string name))
print.Invoke(obj, new object[] {"1233" });
MethodInfo? print = type.GetMethod("Print" ,new Type[]{});//方法重载要把参数类型写上, (方法:public void Print())
print.Invoke(obj, new object[] {});
MethodInfo? DostaticPrint = type.GetMethod("DostaticPrint", BindingFlags.Static | BindingFlags.InvokeMethod| BindingFlags.Public); //调用静态方法 (方法: public static string DostaticPrint(string ss))
DostaticPrint.Invoke(null, new object[] { "1233" });
3.BindingFlags 参数
BindingFlags.Instance : 对象实例 BindingFlags.Static : 静态成员 BindingFlags.Public : 指可在搜索中包含公共成员 BindingFlags.NonPublic : 指可在搜索中包含非公共成员(即私有成员和受保护的成员) BindingFlags.FlattenHierarchy : 指可包含层次结构上的静态成员 BindingFlags.IgnoreCase : 表示忽略 name 的大小写 BindingFlags.DeclaredOnly : 仅搜索 Type 上声明的成员,而不搜索被简单继承的成员 BindingFlags.CreateInstance : 表示调用构造函数。忽略 name。对其他调用标志无效
BindingFlags.InvokeMethod,表示调用方法,而不调用构造函数或类型初始值设定项。对 SetField 或 SetProperty 无效。
4.泛型方法
MethodInfo? PrintT = type.GetMethod("PrintT"); MethodInfo PrintT2 = PrintT.MakeGenericMethod(typeof(string));//先确定参数类型(方法: public void PrintT<T>(T y)) PrintT2.Invoke(obj, new object[] { "1233" });
5.属性和字段
Type model = typeof(ConsoleApp1.Animal); object obj=Activator.CreateInstance(model); PropertyInfo? property= model.GetProperty("Name"); //属性 GetFields字段 property.SetValue(obj,"张三");