在字典中使用谓词作为键,尝试调用值时出错
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 将始终是 true
或 false
,永远不会是 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 相当的时间复杂度=]
我正在尝试使用字典将一个简单的 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 isnull
这似乎符合您的需要。
忽略评论(有效)并回答您的问题:
m => m(randomNumber) != null
永远是真的。谓词中的 return 将始终是 true
或 false
,永远不会是 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 相当的时间复杂度=]