命令某些财产代码的改进

本文关键字:代码 财产 命令 | 更新日期: 2023-09-27 18:17:04

我有一个这样的方法:

public void DoSomething( .... , bool orderByX)
{
    if(orderByX)
    {
       foreach( ... OrderBy(x => x.Location.X))
       {
          ...
       }
    }
    else
    {
       foreach( ... OrderBy(x => x.Location.Y)
       {
          ...
       }
    }
}

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

谢谢。

命令某些财产代码的改进

一个更好的方法,是通过标准,根据该标准进行排序。你可以使用下一个代码作为动力:

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)

在lambda表达式中为OrderBy检查orderByX

public void DoSomething( .... , bool orderByX)
{
    foreach( ... OrderBy(x => orderByX ? x.Location.X : x.Location.Y))
    {
      ...
    }
}

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
    {
       ...
    }
}

只是在其他可行答案之外的另一个选择。