当前位置:  开发笔记 > 编程语言 > 正文

非恒定切换的替代方案

如何解决《非恒定切换的替代方案》经验,为你挑选了1个好方法。

我刚刚了解到switch语句不能使用非恒定条件。一切都很好,我明白了。但这真的意味着我必须大做文章吗?我哭的很丑。

一些上下文:我正在做一个Unity项目,我想打开当前动画状态。检查当前动画状态的一种好方法是比较哈希,这意味着我需要计算动画状态的哈希。计算完它们后,我想打开它们。(写这篇文章时,我意识到我可以将生成的哈希值粘贴到一个常量中,但是现在我仍然想要一个答案)

int state1 = Animator.StringToHash("State1");
int state2 = Animator.StringToHash("State2");
int hash = _myAnimator.GetCurrentAnimatorStateInfo(0).shortNameHash;
switch (hash):
{
case state1:
    //DoStuff
    break;
case state2:
    //Other stuff
    break;
}

最好的方法是什么?



1> Enigmativity..:

您可以使用字典来做到这一点。

尝试这个:

int state1 = Animator.StringToHash("State1");
int state2 = Animator.StringToHash("State2");
int hash = _myAnimator.GetCurrentAnimatorStateInfo(0).shortNameHash;
var cases = new Dictionary, Action>()
{
    { () => hash == state1, () => { /* Do stuff */} },
    { () => hash == state2, () => { /* Do other stuff */} },
};

cases
    .Where(c => c.Key()) // find conditions that match
    .Select(kvp => kvp.Value) //select the `Action`
    .FirstOrDefault() // take only the first one
    ?.Invoke(); // Invoke the action only if not `null`

为了使其更加干净,您可以定义一个Switch这样的类:

public class Switch : IEnumerable
{
    private List _list = new List();

    public void Add(Func condition, Action action)
    {
        _list.Add(new Case(condition, action));
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return _list.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return _list.GetEnumerator();
    }

    public void Execute()
    {
        this
            .Where(c => c.Condition())
            .Select(c => c.Action)
            .FirstOrDefault()
            ?.Invoke();
    }

    public sealed class Case
    {
        private readonly Func _condition;
        private readonly Action _action;

        public Func Condition { get { return _condition; } }
        public Action Action { get { return _action; } }

        public Case(Func condition, Action action)
        {
            _condition = condition;
            _action = action;
        }
    }
}

然后代码如下所示:

int state1 = Animator.StringToHash("State1");
int state2 = Animator.StringToHash("State2");
int hash = _myAnimator.GetCurrentAnimatorStateInfo(0).shortNameHash;
var @switch = new Switch()
{
    { () => hash == state1, () => { /* Do stuff */} },
    { () => hash == state2, () => { /* Do other stuff */} },
};

@switch.Execute();

而且,如果您这样编写,则几乎就像是一条普通switch语句:

var @switch = new Switch()
{
    {
        () => hash == state1,
        () =>
        {
            /* Do stuff */
        }
    },
    {
        () => hash == state2,
        () =>
        {
            /* Do other stuff */
        }
    },
};

推荐阅读
手机用户2402851335
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有