恬静的小魔龙

一、前言

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

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

二、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):
1654860934810.png

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

说了这么多,可能有人会说,我运行时获得类型信息有什么用,我在开发时就能够写好代码呀,干嘛还放到反射中去做呢,不仅麻烦,效率也不行。
这就是一个仁者见仁、智者见智的问题了,就跟早绑定和晚绑定一样,都有不同的应用场景。
存在即合理,合适的使用能够大大提高程序的复用性和灵活性,但是有优点就有缺点。

2-4、反射的优缺点

优点:

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

缺点:

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

    2-5、反射的应用实例

    1、获取程序集信息和类型信息 ```csharp 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;

  1. public void Fun1(){}
  2. public void Fun2(){}
  3. void Start()
  4. {
  5. //获取类型
  6. Type t = GetType();
  7. Debug.Log(t.Name);//类名
  8. Debug.Log(t.Namespace);//所属命名空间
  9. Debug.Log(t.Assembly.ToString());//程序集信息
  10. FieldInfo[] fi = t.GetFields();//获取类中的字段
  11. foreach (var f in fi)
  12. Debug.Log(f.Name);
  13. MethodInfo[] mh = t.GetMethods();//获取所有的方法
  14. foreach (var h in mh)
  15. Debug.Log(h.Name);
  16. }

}

  1. 运行结果:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/277450/1654860996662-1d314814-cdbf-4520-9e61-57a4e2d72880.png#clientId=u8092a2a5-a5a0-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u0a2f7084&margin=%5Bobject%20Object%5D&name=image.png&originHeight=411&originWidth=346&originalType=url&ratio=1&rotation=0&showTitle=false&size=50015&status=done&style=none&taskId=ucc11cf7f-2098-414e-b7f7-df489cdb8db&title=)<br />2、动态创建类型实例并执行其中的方法
  2. ```csharp
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. using System;
  7. using System.Reflection;
  8. public class CreateReflectionDemo : MonoBehaviour
  9. {
  10. void Start()
  11. {
  12. //动态创建类,并执行方法
  13. CreateReflectionClass(1);
  14. }
  15. private void CreateReflectionClass(int index)
  16. {
  17. string AssemblyName = Assembly.GetExecutingAssembly().GetName().Name;//获取程序集名称
  18. string strNameSpace = MethodBase.GetCurrentMethod().DeclaringType.Namespace;//获取命名空间名称;
  19. string strClassName = "Fun" + index;//获取类型名
  20. string fullclassName = strNameSpace + "." + strClassName;//类全名(命名空间.类名称)
  21. MyClass mys = (MyClass)Assembly.Load(AssemblyName).CreateInstance(fullclassName);
  22. mys.GetResult();
  23. }
  24. }
  25. public interface MyClass
  26. {
  27. void GetResult();
  28. }
  29. public class Fun1 : MyClass
  30. {
  31. public void GetResult()
  32. {
  33. Debug.Log("I'm Fun1");
  34. }
  35. }
  36. public class Fun2 : MyClass
  37. {
  38. public void GetResult()
  39. {
  40. Debug.Log("I'm Fun2");
  41. }
  42. }

运行结果:
image.png

三、后记

今天分享了什么是反射,以及反射的使用方法。
反射主要是在运行时获得类型信息的方式,还可以动态创建实例并执行其中的方法。
然后使用了一个简单实例进行演示如何使用反射,但是反射的用法还有很多,需要读者自行摸索。


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

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