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空表示无参方法

 

 

posted @ 2022-10-05 03:49  Akai_啊凯  阅读(826)  评论(0编辑  收藏  举报