4

我有这样的方法:

public void DoSomething( .... , bool orderByX)
{

    if(orderByX)
    {
       foreach( ... OrderBy(x => x.Location.X))
       {
          ...
       }
    }
    else
    {
       foreach( ... OrderBy(x => x.Location.Y)
       {
          ...
       }
    }
}

我想避免 if 产生更少重复的代码(即只有一个 foreach)。这可能吗?

谢谢。

4

3 回答 3

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) 

注意:您可以根据需要泛化选择器(例如传递 holder 或Location,而不是Point自身)。

此外,作为排序标准传递bool会降低代码的可读性。例如,我不知道这个方法做了什么,只需查看它的调用DoSomething(list, false),我必须查看方法签名才能知道false. DoSomething(list, orderByX : false)使用命名参数(可从C# 4.0获得)会好得多,但如果我不按顺序排序X,我怎么知道我按顺序排序Y. 这也将调用代码限制为两个排序标准(您不想添加另一个排序标志,不是吗?)

所以你需要打开你的DoSomething名字来表明你的意图,即你实际上是在命令你的处理。例如TraverseNodesOrderedBy(nodes, point => point.X)

于 2013-06-05T08:35:53.060 回答
3

orderByX入 lambda 表达式OrderBy

public void DoSomething( .... , bool orderByX)
{
    foreach( ... OrderBy(x => orderByX ? x.Location.X : x.Location.Y))
    {
      ...
    }
}
于 2013-06-05T08:28:30.560 回答
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
    {
       ...
    }
}

除了其他可行的答案之外,这只是另一种选择。

于 2013-06-05T08:44:43.910 回答