• c#中的引用命名空间using和反射的使用


    这次6.0版本更新到24年底结束。

    以淘汰框架:WCF,web server ,asp.net webform ,asp.net mvc,asp.net web API 这些都不需要研究。

    需要学习:asp.net core 新知识去学习,被淘汰的都不用去研究了浪费时间,后面代码可能都不支持运行了。

    顶级程序:在新版本6.0中创建控制台应用程序只有一句输出代码,其他代码都被隐藏了。

    Console.WriteLine("Hello World!"); //控制台Console,输出Write,行Line

    本章需要学习3个英语单词:
    namespace:创建命名空间
    using引用,使用:这里表示引用命名空间,第二个作用实例化对象时,对象执行完大括号内立刻释放空间。必须实现IDisposable接口的对象才能使用using释放资源。
    global全局,全面,全球,全世界,整体。

    拿5.0做参考,不过不要学习老版本了,需要学习6.0新版

    隐式导入命名空间

    显示导入命名空间

     二、反射:对某个类的私有成员进行操作。

    另外一种引入命名空间的方式:反射,通过反射代码操作bll文件里的类。其实最大的作用是对某个类不能访问的成员,通过反射手段变得可以访问。

    通过代码找到dll文件。使用反射必须引用:using System.Reflection;

    using System.Reflection; //通过反射类库来操作其他类库,类库就是dll文件。类库名也是命名空间名,其他类库需要引入依赖项
    
    Assembly assembly1 = Assembly.Load("ClassLibrary");//方式1:命名空间定义在启动项目下
    Assembly assembly2 = Assembly.LoadFile(@"完整路径/ClassLibrary.dll");//方式2:不定义在启动项目下,单独创建类库,需要完整路径。
    
    Assembly assembly3 = Assembly.LoadFrom("ClassLibrary.dll");//方法3:是方法一和方法二的结合体。需要加后缀名.dll 完整路径也可以,建议使用

    实例:
    创建一个测试类库

    namespace ClassLibrary //命名空间接收dll文件,也是类库
    {
        public class Class1//用来测试反射手段的调用一些私有成员
        {
            int i { get; set; } //私有字段
            private Class1() { Console.WriteLine("私有的无参构造方法"); }
            public Class1(string str) { Console.WriteLine($"带参数的构造方法:{str}"); }
            public void A() { Console.WriteLine("普通方法"); }
            void B(string str) { Console.WriteLine($"私有的有参数方法:{str}"); }
            void C<T>(string str) { Console.WriteLine($"私有的泛型方法:{str}"); }
        }
    }

    实例化对象的3个步骤:

    using System.Reflection; //通过反射类库来操作其他类库,类库就是dll文件。类库名也是命名空间名,其他类库需要引入依赖项
    
    Assembly assembly = Assembly.LoadFrom("ClassLibrary.dll");//1.找到bll文件(类库)位置
    Type type = assembly.GetType("ClassLibrary.Class1");//2.获取命名空间下的一个类,多个用GetTypes不过数组需要做判断
    //正常的实例化对象【Class1 c =new Class1()】是这样的,静态的知道对象的具体类型才能使用,而反射是动态不知道具体类型只能用object接收。
    object obj = Activator.CreateInstance(type, new object[] {"参数"});//3.实例化对象(动态)如果调用无参构造,那么可以不用写第二个参数new object[]{}

     实例化私有无参构造方法

    var obj1 = Activator.CreateInstance(type);//调用公共的构造方法,public
    var obj2 = Activator.CreateInstance(type, true);//调用私有的构造方法,private

    回到第二步:如何获取命名空间下所有类

    foreach (var type in assembly.GetTypes())
    { 
        Console.WriteLine(type.Name);//2.获取命名空间下所有类
    }

    获取类中所有的构造方法

    foreach (var ctor in type.GetConstructors(BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public))
    { 
        Console.WriteLine($"构造方法:{ctor.Name}");//默认是公开:BindingFlags.Public,加了私有那么公开的也要加。
        foreach (var param in ctor.GetParameters()) { Console.WriteLine($"构造方法参数:{param.ParameterType}"); }
    }

    私有属性的调用

    var propInfo = type.GetProperty("i",BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public);//1.获取私有属性
    propInfo.SetValue(obj, 2000);//2.设置属性值
    Console.WriteLine(propInfo.GetValue(obj, null));//3.执行,也是重新读取值。

    多属性用遍历

    foreach (var propInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) 
    {
        if (propInfo.Name.Equals("i"))
        {
            propInfo.SetValue(obj, 2000);//修改属性值
            Console.WriteLine(propInfo.GetValue(obj, null));//获取值
        }
    }

    私有方法的调用

    //普通方法的调用
    var v = obj as ClassLibrary.Class1;//as命名的好处,不报错,看成类型转换,如果不对就返回null
    v.A();//其实作用调用和静态实例化对象没什么区别【Class1 v  =new Class1();】
    
    //私有方法,通过反射手段调用
    var method = type.GetMethod("B", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
    method.Invoke(obj, new object[] { "参数" });//如果无参可以改为null,或者数组不填参数值。
    
    //私有的泛型方法
    var gm = type.GetMethod("C", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
    var mgm = gm.MakeGenericMethod(new Type[] { typeof(string) });//指定泛型<T>的参数为string。
    mgm.Invoke(obj, new object[] { "参数" });//如果无参可以改为null,或者数组不填参数值。

     反射泛型类

    namespace ClassLibrary //泛型类
    {
        public class Class1<T>//一个泛型参数
        {
            void C<TType>() { Console.WriteLine("泛型方法1"); }
        }
    }
    using System.Reflection; //反射代码的类库
    
    Assembly assembly = Assembly.LoadFrom("ClassLibrary.dll");//1.找到bll文件(类库)位置
    Type type = assembly.GetType("ClassLibrary.Class1`1").MakeGenericType(typeof(int));//2.拿到类:反引号`1表是一个泛型参数,2表示两个...
    object obj = Activator.CreateInstance(type);//3.实例化对象(动态)
    
    //私有的泛型方法
    var gm = type.GetMethod("C", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
    var mgm = gm.MakeGenericMethod(new Type[] { typeof(string) });//多个参数用数组传,一个参数可以不用
    mgm.Invoke(obj, null);//执行,(类,参数)null空表示无参方法

     

  • 相关阅读:
    设计模式学习(十二) 责任链模式
    设计模式学习(十一) 享元模式
    设计模式学习(十) 外观模式
    设计模式学习(九) 装饰模式
    设计模式学习(八) 组合模式
    设计模式学习(七) 桥接模式
    设计模式学习(六) 代理模式
    设计模式学习(五) 适配器模式
    设计模式学习(四) 原型模型
    设计模式(三) 建造者模式
  • 原文地址:https://www.cnblogs.com/longxinyv/p/16754957.html
Copyright © 2020-2023  润新知