【unity】反射机制
前言
很久之前就听说过反射,但不甚理解,今天看到底层终于领悟,遂记录一下相关内容。
C#反射
什么是反射
借用光学中的反射(Reflection)之名,C#中的反射是从对象外部去获取对象内部的各种信息。
这像极了利用波来探测某样物体内部结构,比如金属容器探伤、B超检测体内状况等。
反射是从对象外部获取对象内部的各种信息,具体做法和用途请看如下例子。
以Unity引擎为例,我们来看Unity引擎是如何利用反射机制的。
Unity引擎的反射机制
为Unity编辑器中的游戏对象挂载脚本并编辑好数据,如下(图片仅作为解释说明的例子,不用跟着操作)。
对象上挂载的脚本及其相关数据会保存至场景文件中,如组件名、组件成员变量、成员函数等。
运行时,引擎会加载场景文件,读取场景文件中的数据,实例化节点和组件。
对于客户端开发者来说,新增脚本几乎不可避免;
而对于Unity引擎底层开发来说,加载场景文件时,需要根据组件名来获取类的类型,并对其实例化,挂载到对应游戏对象上。
如果不使用反射,那么每当客户端程序员新增一个脚本时,引擎底层开发人员必须改动相关代码,大抵如下:
于是引入反射来解决这个问题。
反射是怎么做的?
用一种方式来描述任意的类型。即对于每一个类,都建立起一个统一的规则化的描述,使得任意类及其实例均能用该描述来处理。
如何描述一个类?
-
类的实例占有一部分内存,其大小就是该类中所有数据成员的大小。那么描述中可以包含类实例的内存大小。
-
类的数据成员,其描述大抵如下。
{"hp" , type int , 偏移0个字节}
-
类的成员函数,其描述大抵如下。
{"GetHit" , type 成员函数(静态函数) , 在代码段的位置...}
如何描述一个类的实例?
C#为每个类的实例都创建了描述实例,它为Type类型,在System命名空间下。其结构大抵如下。
若要描述上文中的类ReflectionTest,其步骤大抵如下。
编译完成后,我们可以根据编译后的信息,为每个类生成一个描述,写入.exe中。
这样一来,引擎底层就可以根据类的描述来构建实例,访问成员,调用方法了。
调用底层OS的API来分配一个xxx大小的内存,作为对象实例的内存。
调用构造函数,将该内存块传递给构造函数,初始化对应数据。
总结
-
编译每个类时,会为每个类生成一个Type类型的全局数据,其中存放了描述。
API System.Type.GetType("类型名") typeof(T) 根据类型名或类型来获取 描述对象实例。
-
系统已经定义Type类型:FieldsInfos;MethodInfos。
-
通过反射来实例化一个对象。API:Type t -> new relation obj
Activator.CreateInstance (Type)
-
在Type中存放了每个数据成员的偏移和大小,因此可以从对象的内存中读取/设置数据的值。
-
在Type中存放了每个成员函数的地址。
methodInfo = t.getMethod("函数名");
Object returnObj = methodInfo.Invoke(instance , 参数列表);
反射演示
运行结果如下:
出现的问题
当我把数据成员或成员函数设置为私有时,上述代码将无法访问对应数据成员或成员函数。
查阅资料后发现需要使用BindingFlags类型枚举才能访问到私有成员,如下。
参考资料
C#中的反射到底用在哪,通俗解释(unity)、反射的概念及用法
__EOF__

本文链接:https://www.cnblogs.com/OtusScops/p/16746498.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)