2009-10-20 39 views
20

在您的班級中管理guard clause爆炸時,人們會採取哪些方法(如果有)?例如:重構警衛條款

public void SomeMethod<T>(string var1, IEnumerable<T> items, int count) 
{ 
    if (string.IsNullOrEmpty(var1)) 
    { 
     throw new ArgumentNullException("var1"); 
    } 

    if (items == null) 
    { 
     throw new ArgumentNullException("items"); 
    } 

    if (count < 1) 
    { 
     throw new ArgumentOutOfRangeException("count"); 
    } 

    ... etc .... 
} 

在我目前正在研究的項目中,有許多類在公共方法上有一組類似的guard子句。

我知道的.NET 4.0代碼契約的但是這不是我們球隊目前的一個選項。

回答

39

很多項目,我已經看到了使用靜態Guard類。

public static class Guard { 
    public static void ArgumentIsNotNull(object value, string argument) { 
     if (value == null) 
      throw new ArgumentNullException(argument); 
    } 
} 

它使代碼更清潔,在我看來。

Guard.ArgumentIsNotNull(arg1, "arg1"); 
+1

我只是發佈相同的東西。唯一的問題是它把這個方法放在堆棧跟蹤的頂端,而不是頂端的方法,而不是它那麼大。這種模式顯然可以用於不同的類型來檢查一系列的值,等等...... – 2009-10-20 23:42:59

+0

是的,這是我曾經遇到過的唯一問題。雖然很容易找到原始的調用方法。 – 2009-10-20 23:46:19

+1

這與模擬代碼合同的類基本相同。 – 2009-10-21 03:25:38

5

如果你不想下去代碼契約路線,簡化它的一種方式是去除括號:

public void SomeMethod<T>(string var1, IEnumerable<T> items, int count) 
{ 
    if (string.IsNullOrEmpty(var1)) 
     throw new ArgumentNullException("var1"); 

    if (items == null) 
     throw new ArgumentNullException("items"); 

    if (count < 1) 
     throw new ArgumentOutOfRangeException("count"); 

    ... etc .... 
} 

除此之外,還有一些方法,你可以模擬代碼契約,如果你的反對意見是,.NET 4.0是不是黃金時間尚未:

http://geekswithblogs.net/Podwysocki/archive/2008/01/22/118770.aspx

+0

看在上帝的份上,不要這樣做!如果沒有大括號的陳述是一個很好的方式來解決問題。 – EricRRichards 2018-02-27 15:04:06

+1

@EricRRichards:* [聳聳肩] *坦率地說,如果程序員不能在沒有大括號的情況下保持代碼不變(特別是像這樣的不起眼的代碼),他們可能應該回到學校。 – 2018-02-27 15:47:35

3

一種方法減少樣板代碼減少(不完全去除)號守衛條款的目的是瞭解他們存在的原因。通常情況下,我們會防範對參數類型有效的值,但對接受它們的方法無效。換句話說,方法是在由參數類型定義的域的子集上定義的。

解決這一類箱子是嘗試定義一個子類型(例如,更具限制性的接口),並接受該類型作爲參數。您可以在這篇文章中找到一個說明性的例子:Why do We Need Guard Clauses?

當然,這種技術並不適用於所有情況。所有引用類型至少允許空引用。因此,我們的大部分方法都將在域的一部分上定義,而這又需要一個針對null的guard子句。

但積極的一面,這種技術有助於成長的接收是更普遍比所需的參數方法意識。一般來說,通過管道來幫助改善設計。