第二单元 反射

  • 第二单元 反射已关闭评论
  • 173 次浏览
  • A+
所属分类:.NET技术
摘要

反射被誉为是 c#中的黑科技 ,在很多领域中都有反射的身影,例如,我们经常使用的ORM框架,ABP框架 等。


1. 透过现象看本质

反射被誉为是 c#中的黑科技 ,在很多领域中都有反射的身影,例如,我们经常使用的ORM框架,ABP框架 等。

第二单元 反射

反射指程序可以访问、检测和修改它本身状态或行为的一种能力。. 程序集包含模块,而模块包含类型,类型又包含成员。. 反射则提供了封装程序集、模块和类型的对象。. 您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。. 然后,可以调用类型的方法或访问其字段和属性(除了私有构造)。.

 

准备好一个StudentInfo 类,供后面使用

public class StudentInfo {     public void Run()     {         Console.WriteLine($"我是{NickName},我每天都要晨跑");     } ​     public void Run2(int age)     {         Console.WriteLine($"我是{NickName},我今年{age},我每天都要晨跑");     } ​     private string Run3(string nickName)     {         return $"我是{nickName},我是私有方法";     } ​ ​     public StudentInfo()     { ​     }     public StudentInfo(string nickName,int age)     {         NickName = nickName;         Age = age;     } ​     private string _studentNo;//字段     private int Id { get; set; }//属性     public int Age { get; set; }     public string NickName { get; set; } }

 

2. Type声明

表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。这个类是线程安全的。 Type 为 System.Reflection 功能的根,也是访问元数据的主要方式。使用 Type 的成员获取关于类型声明的信息,如构造函数、方法、字段、属性和类的事件,以及在其中部署该类的模块和程序集。 有两种方法可以生成Type类的对象:一种是Typeof(类名),一种是对象调用GetType()函数。

// 方式一 Type type = typeof(StudentInfo);  // 方式二 StudentInfo stu = new(); Type type = stu.GetType();

3. 详细知识点

1. 获取属性

//1.要获取类型 var propList = typeof(StudentInfo).GetProperties();//获取所有的属性 foreach (var propertyInfo in propList) {     Console.WriteLine(propertyInfo.Name); }

 

2. 获取字段

//印证了:属性是对字段的封装 var fields = typeof(StudentInfo).GetFields(BindingFlags.NonPublic | BindingFlags.Instance); foreach (var fieldInfo in fields) {     Console.WriteLine(fieldInfo.Name); }

 

3. 获取类的命名空间

var type = typeof(StudentInfo); var nameSpace = type.Namespace; Console.WriteLine($"命名空间:{nameSpace}");  //获取类名 Console.WriteLine($"类名:{type.Name}"); //类的完整名称:命名空间+类名 Console.WriteLine($"类的完整名称:{type.FullName}");  Console.WriteLine($"它的基类:{type.BaseType}");  Console.WriteLine($"验证委托是否是类:{typeof(Action).IsClass}");

 

4. 创建对象

var tp = typeof(StudentInfo); // 底层其实是调用了 无参构造方法。 对象创建的唯一途径只能是构造方法被调用 var obj = Activator.CreateInstance(tp);  // 再次的验证CreateInstance 其实是调用了构造方法 var instance = Activator.CreateInstance(type1,"任我行",18) as StudentInfo;

 

5. 操作属性

//1.第一步获取类型 var tp = typeof(StudentInfo); //获取某个属性 var prop = tp.GetProperty("NickName");  //StudentInfo stu = new StudentInfo("张三",19); //stu.NickName = "任我行"; //var nickName = stu.NickName; //2.通过反射创建对象(其实调用的是构造函数) var obj = Activator.CreateInstance(tp); prop.SetValue(obj, "李四"); var val = prop.GetValue(obj);//获取属性的值 Console.WriteLine(val);

6. 操作私有字段

var type = typeof(Person); var obj = Activator.CreateInstance(tp); var fieldInfos = type.GetFields(BindingFlags.Instance|BindingFlags.NonPublic); fieldInfos[0].SetValue(obj,10);  var val = fieldInfos[0].GetValue(obj); Console.WriteLine(val);

7. 获取程序集信息

//加载程序集名称  程序必须在当前Bin目录下 var assembly1 = Assembly.Load("ClassLibrary1");    //路径加载程序集名称 var assembly2 = Assembly.LoadFile(@“d:路径 ClassLibrary1 .dll");  //加载程序集后创建对象 Object obj =  assembly1.CreateInstance(“命名空间.类名“,false);   //获取程序集完整路径 string location = Assembly.GetExecutingAssembly().Location;  //获取程序集名称 string file = Assembly.GetExecutingAssembly().GetName().Name;   //获取程序集版本号 string version =  Assembly.GetExecutingAssembly().GetName().Version.ToString();

8. 操作构造函数

私有构造函数不可被操作。

var type = typeof(StudentInfo);  // 获取构造方法 StudentInfo(string nickName,int age) var constructorInfo = type.GetConstructor(new []{typeof(string),typeof(int)}); // 根据构造方法,创建对象 var student = (StudentInfo)constructorInfo.Invoke(new object?[]{"任我行",18}); Console.WriteLine($"姓名={student.NickName},年龄={student.Age}");

 

9. 操作方法

var type = typeof(StudentInfo);  // 获取构造方法 StudentInfo(string nickName,int age) var constructorInfo = type.GetConstructor(new []{typeof(string),typeof(int)}); // 根据构造方法,创建对象 var student = constructorInfo.Invoke(new object?[]{"任我行",18});  // 获取所有的方法,包括私有方法 与 继承至 Object 对象的方法 var methodInfos = type.GetMethods(BindingFlags.Instance|BindingFlags.NonPublic);  // 获取指定方法 var runMethod = type.GetMethod("Run"); // 第二个参数表示被调用的方法参数,null 表示此方法为无参方法 runMethod.Invoke(student, null); 

 

10. 操作特性

自定义一个MyDescriptionAttribute特性,在StudentInfo 类上 加上一个特性 MyDescriptionAttribute

[AttributeUsage(AttributeTargets.All)] public class MyDescriptionAttribute:Attribute {     public string Name { get; set; } }   [MyDescription("学生类的描述信息,我是个学生类")] public class StudentInfo {      // .... 其他信息省略 } var type = typeof(StudentInfo); var desc = type.GetCustomAttribute<MyDescriptionAttribute>(false); Console.WriteLine(desc.Name);

 

配套视频链接:

C# 高级编程,.Net6 系列 开发第三阶段,学完拿捏你的面试官,.net6 进阶学习(已完结)_哔哩哔哩_bilibili