翼度科技»论坛 编程开发 .net 查看内容

第二单元 反射

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
1. 透过现象看本质

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

反射指程序可以访问、检测和修改它本身状态或行为的一种能力。. 程序集包含模块,而模块包含类型,类型又包含成员。. 反射则提供了封装程序集、模块和类型的对象。. 您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。. 然后,可以调用类型的方法或访问其字段和属性(除了私有构造)。.
 
准备好一个StudentInfo 类,供后面使用
  1. public class StudentInfo
  2. {
  3.     public void Run()
  4.     {
  5.         Console.WriteLine($"我是{NickName},我每天都要晨跑");
  6.     }
  7.     public void Run2(int age)
  8.     {
  9.         Console.WriteLine($"我是{NickName},我今年{age},我每天都要晨跑");
  10.     }
  11.     private string Run3(string nickName)
  12.     {
  13.         return $"我是{nickName},我是私有方法";
  14.     }
  15.     public StudentInfo()
  16.     {
  17.     }
  18.     public StudentInfo(string nickName,int age)
  19.     {
  20.         NickName = nickName;
  21.         Age = age;
  22.     }
  23.     private string _studentNo;//字段
  24.     private int Id { get; set; }//属性
  25.     public int Age { get; set; }
  26.     public string NickName { get; set; }
  27. }
复制代码
 
2. Type声明

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

1. 获取属性
  1. //1.要获取类型
  2. var propList = typeof(StudentInfo).GetProperties();//获取所有的属性
  3. foreach (var propertyInfo in propList)
  4. {
  5.     Console.WriteLine(propertyInfo.Name);
  6. }
复制代码
 
2. 获取字段
  1. //印证了:属性是对字段的封装
  2. var fields = typeof(StudentInfo).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
  3. foreach (var fieldInfo in fields)
  4. {
  5.     Console.WriteLine(fieldInfo.Name);
  6. }
复制代码
 
3. 获取类的命名空间
  1. var type = typeof(StudentInfo);
  2. var nameSpace = type.Namespace;
  3. Console.WriteLine($"命名空间:{nameSpace}");
  4. //获取类名
  5. Console.WriteLine($"类名:{type.Name}");
  6. //类的完整名称:命名空间+类名
  7. Console.WriteLine($"类的完整名称:{type.FullName}");
  8. Console.WriteLine($"它的基类:{type.BaseType}");
  9. Console.WriteLine($"验证委托是否是类:{typeof(Action).IsClass}");
复制代码
 
4. 创建对象
  1. var tp = typeof(StudentInfo);
  2. // 底层其实是调用了 无参构造方法。 对象创建的唯一途径只能是构造方法被调用
  3. var obj = Activator.CreateInstance(tp);
  4. // 再次的验证CreateInstance 其实是调用了构造方法
  5. var instance = Activator.CreateInstance(type1,"任我行",18) as StudentInfo;
复制代码
 
5. 操作属性
  1. //1.第一步获取类型
  2. var tp = typeof(StudentInfo);
  3. //获取某个属性
  4. var prop = tp.GetProperty("NickName");
  5. //StudentInfo stu = new StudentInfo("张三",19);
  6. //stu.NickName = "任我行";
  7. //var nickName = stu.NickName;
  8. //2.通过反射创建对象(其实调用的是构造函数)
  9. var obj = Activator.CreateInstance(tp);
  10. prop.SetValue(obj, "李四");
  11. var val = prop.GetValue(obj);//获取属性的值
  12. Console.WriteLine(val);
复制代码
6. 操作私有字段
  1. var type = typeof(Person);
  2. var obj = Activator.CreateInstance(tp);
  3. var fieldInfos = type.GetFields(BindingFlags.Instance|BindingFlags.NonPublic);
  4. fieldInfos[0].SetValue(obj,10);
  5. var val = fieldInfos[0].GetValue(obj);
  6. Console.WriteLine(val);
复制代码
7. 获取程序集信息
  1. //加载程序集名称  程序必须在当前Bin目录下
  2. var assembly1 = Assembly.Load("ClassLibrary1");  
  3. //路径加载程序集名称
  4. var assembly2 = Assembly.LoadFile(@“d:\路径\ ClassLibrary1 .dll");
  5. //加载程序集后创建对象
  6. Object obj =  assembly1.CreateInstance(“命名空间.类名“,false);
  7. //获取程序集完整路径
  8. string location = Assembly.GetExecutingAssembly().Location;
  9. //获取程序集名称
  10. string file = Assembly.GetExecutingAssembly().GetName().Name;
  11. //获取程序集版本号
  12. string version =  Assembly.GetExecutingAssembly().GetName().Version.ToString();
复制代码
8. 操作构造函数

私有构造函数不可被操作。
  1. var type = typeof(StudentInfo);
  2. // 获取构造方法 StudentInfo(string nickName,int age)
  3. var constructorInfo = type.GetConstructor(new []{typeof(string),typeof(int)});
  4. // 根据构造方法,创建对象
  5. var student = (StudentInfo)constructorInfo.Invoke(new object?[]{"任我行",18});
  6. Console.WriteLine($"姓名={student.NickName},年龄={student.Age}");
复制代码
 
9. 操作方法
  1. var type = typeof(StudentInfo);
  2. // 获取构造方法 StudentInfo(string nickName,int age)
  3. var constructorInfo = type.GetConstructor(new []{typeof(string),typeof(int)});
  4. // 根据构造方法,创建对象
  5. var student = constructorInfo.Invoke(new object?[]{"任我行",18});
  6. // 获取所有的方法,包括私有方法 与 继承至 Object 对象的方法
  7. var methodInfos = type.GetMethods(BindingFlags.Instance|BindingFlags.NonPublic);
  8. // 获取指定方法
  9. var runMethod = type.GetMethod("Run");
  10. // 第二个参数表示被调用的方法参数,null 表示此方法为无参方法
  11. runMethod.Invoke(student, null);
复制代码
 
10. 操作特性

自定义一个MyDescriptionAttribute特性,在StudentInfo 类上 加上一个特性 MyDescriptionAttribute
  1. [AttributeUsage(AttributeTargets.All)]
  2. public class MyDescriptionAttribute:Attribute
  3. {
  4.     public string Name { get; set; }
  5. }
  6. [MyDescription("学生类的描述信息,我是个学生类")]
  7. public class StudentInfo
  8. {
  9.      // .... 其他信息省略
  10. }
  11. var type = typeof(StudentInfo);
  12. var desc = type.GetCustomAttribute<MyDescriptionAttribute>(false);
  13. Console.WriteLine(desc.Name);
复制代码
 
配套视频链接:


来源:https://www.cnblogs.com/xuyubing/archive/2023/05/31/17447310.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具