反射:
反射指程序可以访问、检测和修改它本身状态或行为的一种能力。
程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。
您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
优缺点
优点:
- 1、反射提高了程序的灵活性和扩展性。
- 2、降低耦合性,提高自适应能力。
- 3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。
缺点:
- 1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
- 2、使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。
可通过类名、成员的名字类进行对象的实例化、操作类成员
取得Assembly的方法:
Assembly.Load
Assembly.LoadFile
Assembly.LoadFrom
Type对象的Assembly方法
反射的成员:
(1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
常用类:
System.Type 类//通过这个类可以访问任何给定数据类型的信息。
Type类的属性:
Name 数据类型名
FullName 数据类型的完全限定名(包括命名空间名)
Namespace 定义数据类型的命名空间名
IsAbstract 指示该类型是否是抽象类型
IsArray 指示该类型是否是数组
IsClass 指示该类型是否是类
IsEnum 指示该类型是否是枚举
IsInterface 指示该类型是否是接口
IsPublic 指示该类型是否是公有的
IsSealed 指示该类型是否是密封类
IsValueType 指示该类型是否是值类型
Type类的方法:
GetConstructor(),GetConstructors():返回ConstructorInfo类型,用于取得该类的构造函数的信息
GetEvent(),GetEvents():返回EventInfo类型,用于取得该类的事件的信息
GetField(),GetFields():返回FieldInfo类型,用于取得该类的字段(成员变量)的信息
GetInterface(),GetInterfaces():返回InterfaceInfo类型,用于取得该类实现的接口的信息
GetMember(),GetMembers():返回MemberInfo类型,用于取得该类的所有成员的信息
Getproperty(),GetProperties():返回PropertyInfo类型,用于取得该类的属性的信息
System.Reflection.Assembly类//它可以用于访问给定程序集的信息,或者把这个程序集加载到程序中。
先创建一个类
class person//默认partial { public int show(int a) { return a; } public string show(int a,double c) { return a+""+c; } public void showA() { } public static void ShowB() { } private void ShowC() { } private static void ShowD() { } public int a; public static int b; private int c; private static int d; private person(int a,string B) { Console.WriteLine(a + "person类有参函数被调用" + B); } public person() { Console.WriteLine("person类无参函数被调用"); } }
现在开始调用
//通常person p=new person(); //反射: /*BindingFlags: 要访问的方法或字段的权限描述 ,必须要同时具备两个描述 1.要有要访问的成员的访问权限描述 2.要有访问的成员的归属 (静态的是Static 非静态是Instance) */ //通过类名获取一个类型 注意:命名空间 Type T = Type.GetType("ConsoleApp1.person"); //默认会使用public 权限的无参构造方法来实例化 object obj = Activator.CreateInstance(T); //若为true 表示可以匹配任何权限的无参构造函数 object obj1 = Activator.CreateInstance(T,true); //public 权限的 有参构造方法 //object obj2 = Activator.CreateInstance(T,2,"aaa"); //非public 权限的 有参构造方法 object obj3 = Activator.CreateInstance(T,System.Reflection.BindingFlags.NonPublic | BindingFlags.Instance,null,new Object[] { 1,"BBB" },null); //通过反射访问类中的字段 //1 public 非静态 a FieldInfo a = T.GetField("a"); a.SetValue(obj,2); Object aa = a.GetValue(obj); //2访问public 静态 b FieldInfo b = T.GetField("b",BindingFlags.Public | BindingFlags.Static); b.SetValue(null,3);//要访问的是一个静态成员 访问主体是null object bb = b.GetValue(obj); //3访问public 非静态 c FieldInfo c = T.GetField("c",BindingFlags.NonPublic | BindingFlags.Instance); c.SetValue(obj,5); object cc = c.GetValue(obj); //4访问private 静态 d FieldInfo d = T.GetField("d",BindingFlags.NonPublic | BindingFlags.Static); d.SetValue(null,6);//要访问的是一个静态成员 访问主体是null object dd = d.GetValue(obj); //通过反射访问方法 //public 方法A MethodInfo method = T.getmethod("ShowD",BindingFlags.NonPublic | BindingFlags.Static); method.Invoke(null,null); //public 静态方法 //private 方法C //private 静态方法 //获取有参函数 注意:字符串的大小写 MethodInfo info = T.getmethod("show",BindingFlags.Public | BindingFlags.Instance,new Type[] { typeof(int) },null); //type 数组传 方法的参数列表 object x = info.Invoke(obj,new object[] { 1 }); Console.WriteLine(x);
当然了还有很多时候是要通过exe 或者dll 来操作的
这里新建了一个控制台应用程序 在main 方法中 Console.WriteLine("要输出的内容"); 并且将main 函数中的参数改为无参的
string dllName = "ConsoleApp2";//指定dll文件的名字 程序集的名字 string FullName = "ConsoleApp2.Program";//指定程序及的名字+类的名字 Assembly assembly = Assembly.Load(dllName);//加载程序集 Type type = assembly.GetType(FullName);//从程序集中获取指定对象的类型 object xa = Activator.CreateInstance(type);//创建实例 MethodInfo methodx = type.getmethod("Main",BindingFlags.NonPublic | BindingFlags.Static); methodx.Invoke(null,null);//这里如果说在ConsoleApp2 中main函数是传入参数要对应 /*static void Main(string[] args) { } */
参考:https://www.bilibili.com/video/av29432157?t=1973 、https://www.runoob.com/csharp/csharp-reflection.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。