我正在尝试使用字典将一个简单的if-else链变成更具功能性的东西。它工作正常,除非randomNumber不符合任何谓词。有没有更简洁的方法来防止linq空值而不必在where子句中明确地检查它?
Dictionary<Predicate<float>, Func<float, float>> _mutateDict =
new Dictionary<Predicate<float>, Func<float, float>>();
_mutateDict.Add((float x) => x <= 2, f => { return f *= -1f; });
_mutateDict.Add((float x) => x <= 4, f => { return Random.Range(-0.5f, 0.5f); });
_mutateDict.Add((float x) => x <= 6, f => { return f *= 2f; });
float weight = 2f;
float result = _mutateDict
[
_mutateDict
.Keys
.Where(m => m(randomNumber) != null)
.FirstOrDefault()
](weight);
答案 0 :(得分:3)
忽略评论(有效)并回答您的问题:
m => m(randomNumber) != null
永远都是真的。谓词的返回值始终为true
或false
,永远不会null
,这就是为什么当您设置randomNumber = 8
时,您回来-2
:{{ 1}} - &gt; false != null
- &gt; true
为2.0 *= -1
。
其次,当你没有匹配任何谓词时,你的密钥(来自-2
的返回值将为空,并且你不会处理它。
你要么需要使用多行(检查为null),要么像Evk建议的那样拥有一个包罗万象的条目。 Mjwills解决方案也有效,它被称为null conditional operator。
此外,如果您使用FirstOrDefault()
谓词,则可以完全删除.First(m => m(randomNumber))
谓词,将时间复杂度降低到与迭代Where
相当的位置。
答案 1 :(得分:1)
暂不考虑Dictionary
是否是正确的数据结构的问题,我建议尝试:
var result = _mutateDict
[
_mutateDict
.Keys
.Where(m => m(randomNumber) != null)
.FirstOrDefault()
]?.Invoke(weight);
?.Invoke
means:
如果我要调用的函数是
,则返回null
null
似乎符合你的需要。