2009-07-10 132 views
17

我不知道我有多少無數次地編寫代碼來驗證字符串參數:C#:參數驗證:空/空字符串

public RoomName(string name) 
{ 
    if (string.IsNullOrEmpty(name)) 
    { 
     throw new ArgumentException("Cannot be empty", "name"); 
    } 
} 

反正是有避免這種情況?有沒有一些屬性或設計合同機制來避免這種情況?有沒有辦法說:

public RoomName(NotNullOrEmptyString name) 
{ 

而不必實際創建該類型?

+0

您可能會在[使用屬性和方法攔截的參數驗證](http://www.codinginstinct.com/2008/05/argument- validation-using-attributes.html)有用 – Joe 2009-07-10 00:52:26

回答

7

你可以通過代碼注入來實現屬性。

另一種節省一些編碼時間,但仍然給你很多控制的選擇是使用類似CuttingEdge.Conditions的東西。這提供了參數檢查一口流利的接口,所以你可以寫:

name.Requires().IsNotNull(); 
1

雖然問題已經在不久前回答,我一直在思考同樣的問題最近。形式化的代碼契約(自動驗證或檢查)似乎是一個好主意,但一般來說,它們的驗證能力是非常有限的,對於像空字符串或空字符串檢查這樣的簡單檢查,它們需要的代碼量非常多(或更多)比老式的支票。

諷刺的是,在我的字符串大小寫認爲最好的答案確實是一個或兩個類,包裝已檢查不爲空,空或空白的字符串,並圍繞通過這個實例:

public class NonEmptyString : IComparable<NonEmptyString>, ... 
{ 
    private readonly string _value; 

    public NonEmptyString(string value) 
    { 
     if (value == null) 
     { 
      throw new ArgumentNullException("value"); 
     } 
     if (value.Length == 0) 
     {     
      throw NewStringIsEmptyException("value"); 
     } 
     _value = value; 
    } 

    public string Value 
    { 
     get { return _value; } 
    } 

    ... 
} 

public class NonWhiteSpaceString : NonEmptyString 
{ 
    .... 
} 

當然,繞過這些例子並不妨礙你就不必檢查,如果他們自己空,但它有一些大的優勢:

  • 你不必去檢查空或塗白空間字符串一遍又一遍,這可能在字符串的情況下容易出錯被傳遞了很多。
  • 正如我在我的實現中所做的那樣,檢查null與檢查空值(或空白值)不同,因爲要在前一種情況下拋出特定的ArgumentNullException,在第二種情況下拋出一些ArgumentException。
  • 它清楚地表明瞭對字符串值的約束,就像任何包裝類應該做的一樣。事實上,如果你有一個有任何約束的字符串,並且它被傳遞了很多,我總是建議把它封裝在一個封裝了檢查的類中,並使代碼的其餘部分免於麻煩。一個很好的例子就是必須滿足某個正則表達式的字符串。然而,我在這裏轉移問題...
+1

我認爲你需要添加一些跟蹤參數名稱到你的解決方案。這是因爲如果你用`frob(null,「value」)調用`frob(string foo,string bar)`並且得到錯誤消息`System.ArgumentNullException:值不能爲空,大多數人會發現它很混亂。參數名稱:value`而不是`System.ArgumentNullException:值不能爲空。參數名稱:foo` – 2011-11-08 16:16:39