我刚刚了解到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; }
最好的方法是什么?
您可以使用字典来做到这一点。
尝试这个:
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 */ } }, };