awe*_*awe 0 c# linq refactoring
我有这个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);
}
}
Run Code Online (Sandbox Code Playgroud)
我试图将其重构为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);
}
Run Code Online (Sandbox Code Playgroud)
什么我不知道的是或条款这里.在我的脑海里,我需要包括!isTable(e.Key)
处理外部if
/ else if
结构.
我的重构是否正确?这两个代码示例是否产生相同的逻辑功能?
这是一种只用一次电话就可以逃脱的方式isTable
吗?正如我现在所知,我需要将其称为倒置在另一侧||
.
是的,你是对的.这个if 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;
Run Code Online (Sandbox Code Playgroud)
我要补充一点,如果你讨厌三元运算符,你可以使用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;
Run Code Online (Sandbox Code Playgroud)
缓存isTable(e.Key)