zoukankan      html  css  js  c++  java
  • C# 反射

    反射:

    反射指程序可以访问、检测和修改它本身状态或行为的一种能力。

    程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装程序集、模块和类型的对象。

    您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。

    优缺点

    优点:

    • 1、反射提高了程序的灵活性和扩展性。
    • 2、降低耦合性,提高自适应能力。
    • 3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。

    缺点:

    • 1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
    • 2、使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。

    可通过类名、成员的名字类进行对象的实例化、操作类成员

    取得Assembly的方法:
    Assembly.Load
    Assembly.LoadFile
    Assembly.LoadFrom
    Type对象的Assembly方法

    反射的成员:
    (1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
    (2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
    (3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
    (4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
    (5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
    (6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。
    (7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。
    (8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。
     
    常用类:
    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类型,用于取得该类的所有成员的信息
    GetMethod(), GetMethods():返回MethodInfo类型,用于取得该类的方法的信息
    GetProperty(), GetProperties():返回PropertyInfo类型,用于取得该类的属性的信息
    可以调用这些成员,其方式是调用Type的InvokeMember()方法,或者调用MethodInfo, PropertyInfo和其他类的Invoke()方法。
    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, null, 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

  • 相关阅读:
    以太坊 生成助记词和infuru插件
    结束端口占用
    web3无法安装的额解决方案-----yarn命令安装web3
    npm无法安装全局web3的问题
    censeOs账户
    linux go环境安装
    一款非常好用的chrome插件Postman
    js页面刷新的方法location.reload()
    学会使用DNSPod,仅需三步
    wordpress博客服务器迁移过程中总结
  • 原文地址:https://www.cnblogs.com/zeng-qh/p/11158273.html
Copyright © 2011-2022 走看看