我有一些像这样的代码:
[Flags]
public enum someEnumFlag : long
...
if (someFlagEnum)
if (!foo()) return;
if (someFlagEnum)
if (!bar()) return;
// repeat similar lines...
对于每个someFlagEnum
,调用某个方法并返回bool
。如果任何返回值为false
,则整个操作将失败。因此return
。
我该如何简化?我希望“过早返回”部分完好无损,所以我认为foreach
在这里不可行。 (如果我错了,请纠正我)
注意:此someFlagEnum
非常大(20多个标记)。
已编辑的代码。是的,那个枚举真的是System.Enum
。
答案 0 :(得分:4)
if (
(someFlagEnum1 && !foo1()) ||
(someFlagEnum2 && !foo2()) ||
(someFlagEnum3 && !foo3()) ||
(someFlagEnum4 && !bar4()) ||
(someFlagEnum5 && !bar5()) ||
(someFlagEnum6 && !bar6()) ||
(someFlagEnum7 && !bar7()) ||
(someFlagEnum8 && !bar8())
)
{
return;
}
更简单,更难以理解!混淆C#的道路从这里开始! :-): - )
第二种解决方案(C#4.0,适用于其他变体):
var conditions = new Tuple<Func<bool>, Func<bool>>[] {
new Tuple<Func<bool>, Func<bool>>(() => someFlagEnum.flag1, () => foo1()),
new Tuple<Func<bool>, Func<bool>>(() => someFlagEnum.flag2, () => foo2()),
new Tuple<Func<bool>, Func<bool>>(() => someFlagEnum.flag3, () => foo3()),
new Tuple<Func<bool>, Func<bool>>(() => someFlagEnum.flag4, () => foo4()),
new Tuple<Func<bool>, Func<bool>>(() => someFlagEnum.flag5, () => foo5())
}
foreach (var cond in conditions) {
if (cond.Item1() && !cond.Item2()) {
return;
}
}
答案 1 :(得分:3)
如果你有很多这些flagenum值和相应的函数调用,你可以使用字典查找作为稀疏数组来减少代码大小和执行时间:
// set this up in advance of evaluation. Reuse across multiple evals
var lookup = new Dictionary<int, Func<bool>>();
lookup.Add(flag1, () => foo());
lookup.Add(flag2, () => bar());
lookup.Add(flag1 | flag2, () => foo() && bar());
// etc...
对于每个标志组合,您添加一个lambda函数,该函数调用每个相应的函数并返回逻辑及其结果,并使用布尔短路评估。构建起来有点麻烦,但收益在于评估:
// on evaluation, do this:
var func = lookup[someFlagEnum]; // all bits considered at the same time
if (!func()) // all (and only) the corresponding test functions called together
return;
哈希查找和匿名函数调用有一小部分开销,但是如果你有很多正在测试和调用函数的标志,我希望这种查找方法的性能优于语句或带有非常大表达式的if语句,并且比一次循环遍历所有位更快。您需要进行一些性能测量以查看临界点的位置,但我希望它可以低至6或7个标记(低,查找可能比执行6或7个单独的测试更快)