命令某些财产代码的改进
本文关键字:代码 财产 命令 | 更新日期: 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
{
...
}
}
只是在其他可行答案之外的另一个选择。