2011-04-04 53 views
11

我想說:如何在C#中將參數默認爲DateTime.MaxValue?

public void Problem(DateTime optional = DateTime.MaxValue) 
{ 
} 

但是,編譯器抱怨DateTime.MaxValue不是編譯時間常數。

DateTime.MinValue很容易,只要使用默認設置(日期時間)

又見「How do I default a parameter to Guid.Empty in C#?

我不希望使用方法重載,因爲方法我試圖馴服有101個參數!

+2

@Sam Holder但是,8.5k的OP如何以101參數結束了他的方法?我從來沒有發生過我。我真的很想知道爲什麼這看起來是最好的設計。那裏似乎有一個瘋狂的偶合程度。直覺上來說,如果你爲這樣的方法獲得好的代碼度量,我會感到驚訝。 – 2011-04-04 13:23:30

+0

@Sam Holder引用Jerry Seinfeld的話:「如果你有一件滿身都是血跡的T恤,可能洗衣服現在不是你最大的問題。 DateTime問題似乎在參數問題的外圍。 – 2011-04-04 13:28:35

+2

@Simen好吧,101參數可以通過多種方式發生。遺留系統;由於缺乏時間重構(因此招致技術債務),開發團隊擴大行爲;當然,就像這種情況一樣,是大規模的諷刺。加上你認爲101參數是他在做什麼? – 2011-04-04 13:35:08

回答

9

我會替代這種類似:

public void Problem(DateTime? optional = null) 
{ 
    DateTime dateTime = optional != null ? optional.Value : DateTime.MaxValue; 
    // Now use dateTime 
} 
+1

這看起來是最不好的選擇,因爲我不能重寫代碼庫。 – 2011-04-06 09:40:04

+7

@IanRingrose您可能還想使用[null-coalescing操作符](http://msdn.microsoft.com/zh-cn/library/ms173224.aspx)編寫它,即:'DateTime dateTime = optional? DateTime.MaxValue;' – 2012-10-29 21:00:32

3

您可以定義多種功能:

public void Problem() 
{ 
    Problem(DateTime.MaxValue); 
} 
public void Problem(DateTime optional) 
{ 
    // do your stuff here. 
} 

如果調用問題()(無參數)函數調用帶有參數的其他功能。

+0

這可能會令人困惑。兩種方法乍一看都具有相同的簽名。 C#規範[告訴我們](http://stackoverflow.com/questions/2674417/c-4-conflicting-overloaded-methods-with-optional-parameters),編譯器會優先使用方法*,而不使用*可選參數,但你不應該依靠每個人都期望這種行爲。其他建議的解決方案更清晰,更易於維護。 – 2011-04-05 06:30:17

1

loadDefault參數值是常數,也就是說,它不能string.Empty/Guid.Empty等,您可以使用方法重載:

void M(int intValue) 
{ 
    M(intValue, Guid.Empty); 
} 
void M(int intValue, Guid guid) 
{ 
    //do something 
} 
3

我不熟悉C#4.0,但在我會使用重載;

public void Problem() 
{ 
    Problem(DateTime.MaxValue); 
} 
public void Problem(DateTime dt) 
{ 
} 

裏調用之一:

Problem(); //defaults to maxvalue 
Problem(myDateTime); //uses input value 

編輯: 只是把回答的一些評論;

public class FooBar 
{ 
    public bool Problem() 
    { 
     //creates a default person object 
     return Problem(new Person()); 
    } 

    public void Problem(Person person) 
    { 
     //Some logic here 
     return true; 
    } 
} 

public class Person 
{ 
    public string Name { get; private set; } 
    public DateTime DOB { get; private set; } 
    public Person(string name, DateTime dob) 
    { 
     this.Name = name; 
     this.DOB = dob; 
    } 

    /// <summary> 
    /// Default constructor 
    /// </summary> 
    public Person() 
    { 
     Name = "Michael"; 
     DOB = DateTime.Parse("1980-07-21"); 
    } 
} 
+3

如果只有我試圖馴服的方法沒有101參數.. – 2011-04-04 13:07:11

+3

@Ian:hahaha,omg !!我認爲你有一個完全不同的問題!使用參數類。 101個參數...! – 2011-04-04 13:09:04

+0

@Ian Ringrose在任何給定的方法或構造函數中,您的參數永遠不能超過5個(?)。正如@Daniel所建議的那樣,將這些參數抽象爲一個ProblemsArgs類,並將其傳入。 – firefox1986 2011-04-04 13:23:35

2

簡單的答案是你不能用可選參數我不認爲。

如果這是唯一的參數,那麼您可以使用過載。如果這是一個具有許多可選參數的方法的例子,那麼這可能是不可行的。

你可以做的是讓它DateTime?並通過null,那麼解釋null在你的方法DateTime.MaxValue

有一個很好的可選參數的寫法,我會爲你挖掘。

編輯

article here

+0

-1:你的建議非常糟糕,因爲null通常被認爲是'default(T)'的等價物。你會用相當多的方法改變語義。正確的方法是使用重載。 – 2011-04-04 13:08:18

+1

@Daniel幾乎沒有,隨着'默認(日期時間)'與隨後的內部檢查,這是一個完全有效的替代...即使使用不會改變,因爲給它一個空'DateTime?'仍然會觸發默認值。 – 2011-04-04 13:10:43

+0

如果該方法有許多參數,並且OP只是給出問題的示例,則重載可能不可行。如果這是唯一的參數,那麼是超負荷更好。我只是建議一個替代方案,如果他想使用一個可選的參數,因爲我不認爲他能夠以任何其他方式獲得他想要的行爲,並仍然將其作爲可選參數。 – 2011-04-04 13:11:09

2

如果,你在你的意見一個規定,你的方法有很多的參數,你可以把它們都變成一個參數類並使用它的屬性初始值設定項。然後,您將不必初始化所有屬性,並且可以在該類的構造函數中將日期設置爲DateTime.MaxValue

3

你要求做的事根本不可能。 DateTime.MaxValue不是編譯時常量;它實際上是一個只讀字段,它在運行時由靜態構造函數初始化。difference在這裏變得非常重要。可選參數需要編譯時常量,因爲它們直接將值烘焙到代碼中。

但是,真正的問題是您的方法需要101個參數。我從來沒有見過任何響亮的聲音爲重構而哭泣。相反,我的建議是改變你的方法來接受一個類的實例。這也將爲您在指定類的各個屬性的默認值方面提供更大的靈活性。尤其是,您可以指定值爲而不是編譯時常量。

5

根據您的意見之一,您正在嘗試製作一個方法,其中參數更適用於呼叫者。
我強烈建議您創建一個參數類並使用默認值初始化該類的屬性。爲只接受一個參數的方法提供重載:參數類。
這將真正改善您的方法的用法,因爲如果用戶只需要更改一個參數,甚至可以重用其參數類實例。

+0

我在思考更多_multiple_參數類的行。如果這些參數中的某些參數「不屬於羣組」,那將會很奇怪。 – 2011-04-04 13:53:30

+0

@Simen:在不知道他的代碼的情況下,我們無法知道,但如果他們屬於小組,你的建議就有意義了。 – 2011-04-04 13:57:32

+0

我想可能會出現這樣的情況:一個類正在處理很多非常不相關的原子信息元素:如果您試圖在弱類型配置文件和應用程序核心之間定義強類型接口。不過,我相信應該避免通過一個方法調用來傳遞它們。 – 2011-04-04 14:01:01