I have this foreach loop:
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);
}
}
I have tried to refactor this to 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);
}
What I’m not sure of is the or clause here. In my head I need to include !isTable(e.Key) to handle the outer if/else if structure.
Am I thinking right with my refactoring? Are these two code examples resulting in the same logical functionality?
Is it a way I can get away with only one call to isTable? As I have it now I need to call it inverted on the other side of the ||.
Yes you are right. This if
isTabledoesn’t have side effects (doesn’t do anything but check something) and is deterministic based on the parameters (so calling it twice with e.Key always result in the same value). Still it could (it could be a premature optimization… Who knows?) probably be better to keep it more similar to the originalifand use a ternary operator (? :) so not to recheckisTableI’ll add that if you hate ternary operators, you could use the
letkeyword:to cache the isTable(e.Key)