反射

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,"张三");

 

posted @ 2022-03-29 22:02  乌柒柒  阅读(27)  评论(0编辑  收藏  举报