在字典中使用谓词作为键,尝试调用值时出错

Using Predicates as Key in Dictionary, Getting Error When Trying To Call Value

我正在尝试使用字典将一个简单的 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);

抛开 Dictionary 是否是正确的数据结构的问题,我建议尝试:

var result = _mutateDict
[
    _mutateDict
    .Keys
    .Where(m => m(randomNumber) != null)
    .FirstOrDefault()
]?.Invoke(weight);

?.Invoke means:

return null if the function I am about to invoke is null

这似乎符合您的需要。

忽略评论(有效)并回答您的问题:

m => m(randomNumber) != null 永远是真的。谓词中的 return 将始终是 truefalse,永远不会是 null,这就是为什么当您设置 randomNumber = 8 时返回 -2: false != null -> true -> 2.0 *= -1-2.

其次,当你匹配你的谓词 none 时,你的键(来自 FirstOrDefault() 的 return 将为空,你没有处理它。

要么需要使用多行(检查是否为空),要么像 Evk 所建议的那样拥有一个包罗万象的条目。 Mjwills 解决方案也有效,它被称为 null conditional operator.

此外,如果您使用 .First(m => m(randomNumber)) 谓词,则可以完全删除 Where 谓词,将时间复杂度降低回与迭代 List<>.[=25 相当的时间复杂度=]