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