2013-06-05 47 views
4

我有這樣的方法:的OrderBy某些屬性 - 代碼改進

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

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

我想避免如果產生較少的重複的代碼(即,只有一個的foreach)。這可能嗎?

謝謝。

回答

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

+1代表自我描述性代碼。 – KingCronus

3

檢查orderByX在λ表達式爲OrderBy

public void DoSomething(.... , bool orderByX) 
{ 
    foreach(... OrderBy(x => orderByX ? x.Location.X : x.Location.Y)) 
    { 
     ... 
    } 
} 
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 
    { 
     ... 
    } 
} 

又一個除了其他可行的答案選項。