Unity3D日常开发Unity3D中 C#反射Reflection的使用

Posted 恬静的小魔龙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3D日常开发Unity3D中 C#反射Reflection的使用相关的知识,希望对你有一定的参考价值。

推荐阅读

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

你的点赞就是对博主的支持,有问题记得留言:

一、前言

今天分享一个平时开发比较少接触到的概念——反射,最近也是在写代码的时候用到了,就分享出来,一方面是对自己学到的知识的总结,另一方面也是为了帮助后来的人。

反射虽然用的不多,但是存在既有道理,在接下来的小节中会讲到反射的应用场景。

二、C#反射(Relection)学习

2-1、什么是反射

反射,英文名Relection,是.Net中获取运行时类型信息的方式,.Net的应用程序由三部分组成:

  • 程序集(Assembly)
  • 模块(Module)
  • 类型(Class)

而反射提供一些借口,让程序可以在程序运行时获得这几个组件的信息,比如说:

  • 获取正在运行的程序集,根据程序集中的类型信息,创建该类型的实例。
  • 获取对象的类型信息,比如方法、构造器、属性等。
  • 获取类的方法名称、参数、返回值等。

总结一句话就是:程序访问、检测和修改它本身状态的一种机制,动态创建实例并执行其中的方法。

2-2、反射的应用场景

说了这么多,反射好像很有用,又好像很没用的样子,到底什么地方用到呢?

反射主要在下列情况中很有用:

  • 在运行时查看特性信息,访问程序元数据中的属性。
  • 在运行时查看集合中的类型,并且实例化这些类型。
  • 在运行时构建新类型,并且使用这些类型执行一些任务。
  • 在运行时绑定、访问创造类型的方法。

举个简单的例子,我们有一个程序play.exe,使用了say.dllwalk.dll,突然客户说要增加一个跑的功能,那么我们只需要按照我们约定的规则制作一个run.dll,之前的play.exe就不需要做任何修改,就能直接使用run.dll,就不需要再打开编辑器,将run.dll导进去,再生成play.exe


更多作用参看下表(该表引用自https://blog.csdn.net/q493201681/article/details/82623802):

类 型作用
Assembly定义和加载程序集,加载程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。
Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
ConstructorInfo了解构造器的名称,参数,访问修饰符(如public或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或GetConstructor方法来调用特定的构造函数。
MethodInfo了解方法的名称,返回类型,参数,访问修饰符(如public或private)和实现详细信息(如abstract或virtual)等。使用type的GetMethods或GetMethod方法来调用特定的方法。
FieldInfo了解字段的名称,方法修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
EventInfo了解事件的名称,事件处理程序数据类型,自定义特性,声明类型或反射类型等,并添加或移除事件处理程序。
PropertyInfo了解属性的名称,数据类型,声明类型,反射类型和只读或可写状态等,并获取或设置属性值。
ParameterInfo了解参数的名称,数据类型,参数是输入参数还是输出参数等,以及参数在方法签名中的位置等。

2-3、运行时获得类型信息有什么用

说了这么多,可能有人会说,我运行时获得类型信息有什么用,我在开发时就能够写好代码呀,干嘛还放到反射中去做呢,不仅麻烦,效率也不行。

这就是一个仁者见仁、智者见智的问题了,就跟早绑定和晚绑定一样,都有不同的应用场景。

存在即合理,合适的使用能够大大提高程序的复用性和灵活性,但是有优点就有缺点。

2-4、反射的优缺点

优点:

  • 提高了程序的灵活性和拓展性
  • 减低耦合性,提高程序适应能力
  • 允许在运行时创建和控制类对象,无序提前硬编码目标类

缺点:

  • 反射是一种解释操作,在使用的时候效率要比直接代码要慢,推荐使用在对灵活性和拓展性要求比较高的项目中。
  • 反射会让代码变得复杂,反射绕过了源代码的技术,对于维护会带来一些问题,比直接代码要复杂。

2-5、反射的应用实例

1、获取程序集信息和类型信息

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
using System;

public class ReflectionGetInfo : MonoBehaviour

    public string Name;
    public int Age;
    public bool Sex;

    public void Fun1()
    public void Fun2()

    void Start()
    
        //获取类型
        Type t = GetType();
        Debug.Log(t.Name);//类名
        Debug.Log(t.Namespace);//所属命名空间
        Debug.Log(t.Assembly.ToString());//程序集信息
        FieldInfo[] fi = t.GetFields();//获取类中的字段
        foreach (var f in fi)
            Debug.Log(f.Name);
        MethodInfo[] mh = t.GetMethods();//获取所有的方法
        foreach (var h in mh)
            Debug.Log(h.Name);
    

运行结果:

2、动态创建类型实例并执行其中的方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Reflection;

public class CreateReflectionDemo : MonoBehaviour

    void Start()
    
        //动态创建类,并执行方法
        CreateReflectionClass(1);
    

    private void CreateReflectionClass(int index)
    
        string AssemblyName = Assembly.GetExecutingAssembly().GetName().Name;//获取程序集名称
        string strNameSpace = MethodBase.GetCurrentMethod().DeclaringType.Namespace;//获取命名空间名称;
        string strClassName = "Fun" + index;//获取类型名
        string fullclassName = strNameSpace + "." + strClassName;//类全名(命名空间.类名称)
        MyClass mys = (MyClass)Assembly.Load(AssemblyName).CreateInstance(fullclassName);
        mys.GetResult();
    

public interface MyClass

    void GetResult();

public class Fun1 : MyClass

    public void GetResult()
    
        Debug.Log("I'm Fun1");
    

public class Fun2 : MyClass

    public void GetResult()
    
        Debug.Log("I'm Fun2");
    

运行结果:

三、后记

今天分享了什么是反射,以及反射的使用方法。

反射主要是在运行时获得类型信息的方式,还可以动态创建实例并执行其中的方法。

然后使用了一个简单实例进行演示如何使用反射,但是反射的用法还有很多,需要读者自行摸索。


博主还有跟多宝藏文章等待你的发掘哦:

专栏方向简介
Unity3D开发小游戏小游戏开发教程分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。
Unity3D从入门到进阶入门从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。
Unity3D之UGUIUGUIUnity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。
Unity3D之读取数据文件读取使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。
Unity3D之数据集合数据集合数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。
Unity3D之VR/AR(虚拟仿真)开发虚拟仿真总结博主工作常见的虚拟仿真需求进行案例讲解。
Unity3D之插件插件主要分享在Unity开发中用到的一些插件使用方法,插件介绍等
Unity3D之日常开发日常记录主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等
Unity3D之日常BUG日常记录记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。

以上是关于Unity3D日常开发Unity3D中 C#反射Reflection的使用的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D日常开发Unity3D中使用反射消灭Switch语句

Unity3D日常开发Unity3D中使用反射消灭Switch语句

Unity3D日常开发Unity3D中屏蔽不想显示的黄色警告消息

Unity3D日常开发Unity3D中屏蔽不想显示的黄色警告消息

Unity3D日常开发Unity3D中实现箭头指向目标点的效果

Unity3D日常开发Unity3D工具之UnityForSVN