首页 > 解决方案 > 如何在不中断事件运行其他操作的情况下避免重复 if 语句?

问题描述

在这个问题中有两个类相互作用。我想说明我正在使用 Unity:

  1. 任务处理程序
public class TaskHandler{

    public event Action<GameObject> TaskResponses;

    private void Update(){
        if (someCondition){
            TaskResponses?.Invoke(taskObj);
        }
    }
}
  1. 任务库
public class TaskBase: MonoBehaviour{

    private TaskHandler taskHandler;

    private void Start(){
        taskHandler = gameObject.GetComponent<TaskHandler>();
        taskHandler.TaskResponses += TaskResponse;
    }

    private void TaskResponse(GameObject taskObj){
        //if check so that only specific TaskResponses run.
        if (taskObj == gameObject){
                //functions
            }
    }

}

我面临的问题是扩展TaskResponse().

public class SpecificTask{

    public override void TaskResponse(GameObject taskObj)
    {
        base.TaskResponse(taskObj);

        //another if check
        if (taskObj == thisTaskObj){
            //some other functionality
        }
    }
}

我不想再做一次if检查。我尝试了以下方法:

public class TaskBase: MonoBehaviour{
    //Start() method omitted

    private void TaskResponse(GameObject taskObj){
        //if check so that only specific TaskResponses run.
        if (taskObj == gameObject){
                //functions
            }
        else{
            //Effectively stops code from SpecificTask to continue running,
            //But other Actions are no longer called.
            return;
        }
    }

}

但该return语句TaskReponses()从其他类停止运行。我的意思是,如果我有 Class Task1and Task2, and Task1'sTaskResponse()首先运行,但它运行 else 语句,它会停止并且不运行Task2's TaskResponse()

如何改进我的代码以停止编写重复if检查,同时让我的代码检查所有Action我想要的?我不应该event在这种情况下使用吗?

谢谢!

标签: c#unity3devents

解决方案


您可以不设置void,而是bool指示该方法是否成功终止或中止,例如

public class TaskBase
{
    public virtual bool TaskResponse(GameObject taskObj)
    {
        if(taskObj != thisObj) return false;

        // Default stuff to happen

        return true;
    }
}

然后你可以做

public class MyTask
{
    public override bool TaskResponse (GameObject taskObj)
    {
        if(!base.TaskResponse(taskObj)) return false;

        // Default stuff already happened
        // Now you can add additional stuff here

        return true;
    }
}

或者,如果您想if完全避免这种检查,我也经常使用单独的方法,例如

public class TaskBase
{
    public void TaskResponse (GameObject taskObj)
    {
        if(taskObj != thisObj) return;

        TaskResponseInternal();
    }

    protected virtual void TaskResponseInternal() 
    {
        // Default stuff to happen
    }
}

然后简单地覆盖它

public class MyTask
{
    protected override void TaskResponseInternal ()
    {
        // If you want also the default stuff
        base.TaskResponseInternal();

        // Additional stuff to happen
    }
}

推荐阅读