2015-07-28 77 views
0

修改參數值被認爲是一種反模式,但我覺得它在C#中的可選參數有時是有用的:是否確定改變可選參數

public void Foo(int p1, MyClass fooObj = null) 
{ 
    if (fooObj == null) 
    { 
     fooObj = LoadFooObj(.... 
    } 

    . . . 
} 

是這裏的東西可能有害的我可能會丟失?

謝謝。

+0

這是完全常見的,並確定。關於不改變參數值的想法可能是針對人們過去編寫的100多行方法。如果你只有短的方法,這不會是一個問題。 –

回答

3

這絕對沒問題。事實上,這是一個讓參數可選的好方法,不需要將數值作爲常量進行烘焙。

您可以使用空合併運算符,使其略微更具可讀性,但:

public void Log(string message, DateTime? timestamp = null) 
{ 
    DateTime actualTimestamp = timestamp ?? DateTime.UtcNow; 
    ... 
} 

一個缺點:

fooObj = fooObj ?? LoadFooObj(); 

使用值類型相同的方法,你甚至可以考慮這是因爲它可以防止null被用作「正常」有意義的值 - 雖然 - 考慮您是否會在特定情況下需要這樣的值。

4

如果你覺得它有味道,那麼簡單的超載怎麼樣。

public void Foo(int p1, MyClass fooObj) 
{ 
    . . . 
} 

public void Foo(int p1) 
{ 
    var fooObj = LoadFooObj(....); 
    Foo(p1, fooObj); 
} 

這樣就明確了每種方法的作用,並且不會改變調用中的參數。

+0

是的,你的代碼看起來不錯,謝謝。關鍵是我不知道是否原始代碼味道) –

+0

唯一的問題是它很難篩選出我被稱爲沒有選項的地方。如果你把它們分開,你可以很容易地找到ide中的所有引用 –

+0

如果你想擁有多個可選參數也很棘手 - 重載次數爆炸。 –

2

我要去爭辯喬恩斯基特完全相反,並說這不是罰款,原因有二:

  1. 儘可能,所有變量(包括參數)應被視爲是不可變的。如果你真的必須改變它們的價值。這導致更清晰,更易於理解的代碼。
  2. 避免可選參數。一個帶有可選參數的方法,然後立即測試該參數是一個清晰的代碼味道:你有兩條路徑通過代碼,所以使它有兩種方法。

你可能只是重載Foo,但想想這些方法的作用:他們可能應該被賦予不同的名稱來描述他們做不同事情的事實。不要依賴評論來解釋這一點;用代碼本身清楚說明。

+0

我不明白爲什麼(2)特別適用於可選參數。當然,同樣的邏輯將適用於任何參數,無論它是否具有默認值? –

+0

它也適用於具有布爾參數的任何方法嗎?我只能使用兩種名稱略有不同的方法。 –

+0

@ArturUdod,絕對這個規則應該應用於布爾參數。 –