首页 > 其他分享 >第二单元 反射

第二单元 反射

时间:2023-05-31 20:55:54浏览次数:44  
标签:反射 Console string 第二 typeof StudentInfo var type 单元

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

标签:反射,Console,string,第二,typeof,StudentInfo,var,type,单元
From: https://www.cnblogs.com/xuyubing/p/17447310.html

相关文章

  • AI实战营第二期 | 环境配置及安装
    AI实战营第二期|环境配置及安装强烈推荐使用mim来管理OpenMMLabrepoOpenMMLabrepo不要mim和pip混用OpenMMLab1.0和OpenMMLab2.0环境分离,不要耦合在一个环境里面以下是比较推荐的初学者配置方式,进阶之后推荐使用软链接模式,详见:OpenMMLab2.0源码阅读和调......
  • JDK高版本反射修改 private static fianl 修饰的对象
    在JDK高版本中,Java语言规范已经更新,因可能会破坏Java语言的安全性和稳定性,不再允许通过反射改变final字段的值,需要自己做一下处理。 创建工具类importjava.lang.reflect.Field;importsun.misc.Unsafe;publicclassFieldUtil{privatestaticUnsafeunsafe......
  • 校企合作 | 东软学院人工智能实训专场会(第二期)顺利召开
    东软学院第二期人工智能实训专场会近日,在东软学院老师们的积极组织下,人工智能产业应用研究院(以下简称研究院)开展的第二期人工智能实训专场会顺利召开。本次研究院也为东软学院第一期实训通过的学生发放相关项目实训证明。一期实训通过学生领取项目实训证明第二期实训专场会由研究院......
  • 第十三单元 补充知识
    1.泛型泛指某种类型。1、使用参数形式定义2、使用时传入具体类型3、编译时检查类型安全4、逻辑上是多个不同类型泛型与非泛型之间的区别性能高:可以避免装箱和拆箱操作类型安全:在进行类型转换的时候不会抛出异常代码重用:定义一次,用许多种不同类型实例化代码扩......
  • 第十一单元 面向对象三:继承与多态
    假设老师类设计如下:class老师类{属性:姓名,性别,生日,工资行为:吃饭,跑步,教学}学生类设计如下:class老师类{属性:姓名,性别,生日,班级行为:吃饭,跑步,学习}我们秉承着,让最简洁的代码,实现最最强大的功能原则,能否让上述案例中的重复代码进行优化呢?我们能......
  • 第十单元 面向对象二:静态类与静态成员
    前言我们天天都在使用Console.WriteLine("Helloworld");​Console.ReadLine("");​Arrays.Sort()为什么Console类调用方法不需要实例化而可以直接调用呢?我们可以查看Console的源码发现Console类定义如下:publicstaticclassConsole{//...}......
  • 第九单元 面向对象一:类与对象
    假设,班级里40位同学,我们用程序保存40位学生的信息:学号,姓名,性别,生日,身份证号。如果是你,你会怎么实现?小菜同学拿到这个题,奋书疾笔,马上写出如下代码:ArrayListlist=newArrayList();​stringstuNo1="10001";stringname1="张三";stringsex="男";Datetimebirthday1=D......
  • 代码随想录算法训练营第二十一天|530. 二叉搜索树的最小绝对差、
    【参考链接】530.二叉搜索树的最小绝对差【注意】1.二叉搜索树采用中序遍历,其实就是一个有序数组。2.使用双指针,更快。【代码】1#Definitionforabinarytreenode.2#classTreeNode(object):3#def__init__(self,val=0,left=None,right=None):4#......
  • 第八单元 数组与集合
    1.数组(Array)数组是一个存储相同类型元素的固定大小的顺序集合。数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合。声明数组变量并不是声明number0、number1、...、number99一个个单独的变量,而是声明一个就像numbers这样的变量,然后使用numbers[0]、numbers[......
  • SWE学习-第二十二节
    自动线号 重新编号 比如断路器序号乱了,就选择设备 然后确定......