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

Posted 恬静的小魔龙

tags:

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

推荐阅读

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

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

一、前言

在开发中常常会用到Switch语句,Switch语句是一种选择语句,指针某个表达式的值进行判断,从而执行哪一段的代码,但是表达式的值多了之后,Switch语句往往特别长,很不美观,接下来,博主就带领大家使用反射来消灭Switch语句。

关于反射的用法,可以参考我这篇文章:https://blog.csdn.net/q764424567/article/details/123503141

二、使用反射消灭Switch语句

2-1、构建Switch应用场景

比如说,我们有一个按钮,按钮绑定了一个事件,根据按钮传递过来的值决定今天要吃什么水果:

private void BtnEvent(int index)
    
        switch (index)
        
            case 0:
                Debug.Log("今天吃苹果");
                break;
            case 1:
                Debug.Log("今天吃香蕉");
                break;
            case 2:
                Debug.Log("今天吃梨");
                break;
            case 3:
                Debug.Log("今天火龙果");
                break;
            default:
                break;
        
    

现在看来这个switch 语句还不是很长,但是把所有的水果都放上去,中间再加点逻辑代码,那这长度就难以想象了,而且这种写法Switch还不利于维护,就算你把所有的水果加上去了,但是出现新的水果还是会修改switch 内部的语法。

那么接下来就解决这个switch 语句吧。

2-2、使用工厂方法解决

我们可以创建一个工厂接口,然后每个Switch中case设计成一个工厂类,工厂类实现工厂接口:

public interface EatFruit

    void GetResult();

public class Fruit0 : EatFruit

    public void GetResult()
    
        Debug.Log("Eat Apple");
    

public class Fruit1 : EatFruit

    public void GetResult()
    
        Debug.Log("Eat Bananas");
    

public class Fruit2 : EatFruit

    public void GetResult()
    
        Debug.Log("Eat Pear");
    

public class Fruit3 : EatFruit

    public void GetResult()
    
        Debug.Log("Eat Pitaya");
    

调用代码:

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

public class CreateReflectionDemo : MonoBehaviour

	//调用代码
    private void BtnEvent(int index)
    
        EatFruit ef = new Fruit0();
        ef.GetResult();
    

public interface EatFruit

    void GetResult();

public class Fruit0 : EatFruit

    public void GetResult()
    
        Debug.Log("Eat Apple");
    

public class Fruit1 : EatFruit

    public void GetResult()
    
        Debug.Log("Eat Bananas");
    

public class Fruit2 : EatFruit

    public void GetResult()
    
        Debug.Log("Eat Pear");
    

public class Fruit3 : EatFruit

    public void GetResult()
    
        Debug.Log("Eat Pitaya");
    

运行结果:

那这肯定就有小伙伴说了,你这也不行呀,index参数都没有用,而且吃不同的水果还需要创建不同的类,那不还得用Switch,你搁着浪费时间呢。

桥的麻袋!还没放大招!接下来使用反射+工厂方法彻底解决。

2-3、反射+工厂方法

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

public class CreateReflectionDemo : MonoBehaviour

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

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

public interface EatFruit

    void GetResult();

public class Fruit0 : EatFruit

    public void GetResult()
    
        Debug.Log("Eat Apple");
    

public class Fruit1 : EatFruit

    public void GetResult()
    
        Debug.Log("Eat Bananas");
    

public class Fruit2 : EatFruit

    public void GetResult()
    
        Debug.Log("Eat Pear");
    

public class Fruit3 : EatFruit

    public void GetResult()
    
        Debug.Log("Eat Pitaya");
    

使用Assembly.Load根据获取的参数动态创建类,并执行相对应的函数,运行结果:


代码还可以精简亿点:

private void BtnEvent(int index)

   EatFruit mys = (EatFruit)Assembly.Load("Assembly-CSharp").CreateInstance(".Fruit" + index);
   mys.GetResult();

到这一步,就不再需要Switch去对表达式的值进行判断,而是根据得到的值使用反射和工厂方法动态创建对应的类,然后对应的类再执行相应的方法。

如果要增加其他水果,只需要继承水果类,然后实现方法即可,并不需要改变内部的代码。

三、后记

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

专栏方向简介
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中使用反射消灭Switch语句的主要内容,如果未能解决你的问题,请参考以下文章

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

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

Unity3D日常开发Unity3D中使用数据类保存数据,持久保存数据数据存放在跨场景调用数据类

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

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

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