用if - else结构将foreach重构为LINQ
本文关键字:foreach 重构 LINQ 结构 if else | 更新日期: 2023-09-27 18:11:56
我有这个foreach循环:
var includedElements = new HashSet<int>();
foreach(var e in elements)
{
var include = false;
if(isTable(e.Key))
{
if(tables.ContainsKey(e.Key)
{
if(tables[e.Key].Elements
.Any(subElem => shouldBeIncluded(subElem.Key) ) )
{
include = true;
}
}
}
else if(shouldBeIncluded(e.Key))
{
include = true;
}
if(include){
includedElements.Add(e.Key);
DoSomeMoreStuff(e);
}
}
我试着将它重构为LINQ:
var query =
from e in elements
where
(
isTable(e.Key)
&& tables.ContainsKey(e.Key)
&& tables[e.Key].Elements
.Any(subElem => shouldBeIncluded(subElem.Key) )
) || (
!isTable(e.Key)
&& shouldBeIncluded(e.Key)
)
select e;
foreach(e in query){
includedElements.Add(e.Key);
DoSomeMoreStuff(e);
}
我不确定的是这里的或子句。在我的脑海中,我需要包括!isTable(e.Key)
来处理外部的if
/else if
结构。我的重构思路正确吗?这两个代码示例是否产生相同的逻辑功能?
这是一种方法,我可以摆脱只有一个呼叫isTable
?现在我需要把它命名为倒立在||
的另一边
你是对的。如果isTable
没有副作用(除了检查之外什么都不做),并且基于参数是确定的(所以用e.Key调用它两次总是会得到相同的值)。然而,它可能(它可能是过早的优化…谁知道呢?)可能最好保持它与原来的if
更相似,并使用一个三元运算符(? :
),这样就不用重新检查isTable
var query =
from e in elements
where
isTable(e.Key) ?
tables.ContainsKey(e.Key) && tables[e.Key].Elements
.Any(subElem => shouldBeIncluded(subElem.Key) )
:
shouldBeIncluded(e.Key)
select e;
我要补充一点,如果你讨厌三元操作符,你可以使用let
关键字:
var query =
from e in elements
let isT = isTable(e.Key)
where
( isT && tables.ContainsKey(e.Key) && tables[e.Key].Elements
.Any(subElem => shouldBeIncluded(subElem.Key) ) )
||
( !isT && shouldBeIncluded(e.Key) )
select e;
你是正确的。else if
表示if
条件不匹配,因此
if(A) {
if(B) {
if(C) {
include = true;
}
}
}
else if(D) {
include = true;
}
等价于
if(A) {
if(B) {
if(C) {
include = true;
}
}
}
if(!A && D) {
include = true;
}
相当于
if ((A && B && C) || (!A && D)) {
include = true;
}