我有这样的方法:
public void DoSomething( .... , bool orderByX)
{
if(orderByX)
{
foreach( ... OrderBy(x => x.Location.X))
{
...
}
}
else
{
foreach( ... OrderBy(x => x.Location.Y)
{
...
}
}
}
我想避免if产生较少重复的代码(即只有一个foreach)。这可能吗?
感谢。
答案 0 :(得分:15)
更好的方法是通过标准,按顺序排序。您可以使用下一个代码作为动机:
public void DoSomething<T>( .... , Func<Point, T> orderbySelector)
{
foreach( ... OrderBy(p => orderbySelector(p.Location)))
{
...
}
}
现在你可以:
DoSomething(mySequence, point => point.X)
或
DoSomething(mySequence, point => point.Y)
注意:您可以根据需要概括选择器(例如传递持有者或Location
,而不是Point
本身)。
此外,将bool
作为排序条件传递会降低代码的可读性。例如,我不知道这个方法的作用,只需查看它的调用DoSomething(list, false)
,我必须看到方法签名才能知道false
的语义是什么。使用命名参数DoSomething(list, orderByX : false)
(可从 C#4.0 获得)会好得多,但如果我没有按X
订购,那么,我怎么知道,然后我按Y
排序?。这也限制了调用代码只有两个排序标准(你不想添加另一个排序标志,不是吗?)
因此,您需要打开您的意图,使DoSomething
名称显示,您实际上是在命令处理。例如TraverseNodesOrderedBy(nodes, point => point.X)
答案 1 :(得分:3)
检查orderByX
OrderBy
public void DoSomething( .... , bool orderByX)
{
foreach( ... OrderBy(x => orderByX ? x.Location.X : x.Location.Y))
{
...
}
}
答案 2 :(得分:2)
LINQ查询是可组合的,这意味着您可以在执行它们之前构建它们:
public void DoSomething( .... , bool orderByX)
{
var query = ... ;
if (orderByX)
query = ... .OrderBy(x => x.Location.X);
else
query = ... .OrderBy(x => x.Location.Y);
foreach(var x in query) // deferred execution
{
...
}
}
除了其他可行的答案之外,还有另一种选择。