【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之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和坑,让后来人可以有些参考。

猜你喜欢

转载自blog.csdn.net/q764424567/article/details/123504712