2009-10-01 74 views
8

我一直在想,能夠做這樣的事情會很有用,例如,檢查空引用的參數並最終拋出異常。
這樣可以節省一些打字的時間,並且如果添加了新的參數,也會使忘記添加檢查成爲不可能。是否可以迭代C#中的方法參數?

回答

15

好了,除非你算上:

public void Foo(string x, object y, Stream z, int a) 
{ 
    CheckNotNull(x, y, z); 
    ... 
} 

public static void CheckNotNull(params object[] values) 
{ 
    foreach (object x in values) 
    { 
     if (x == null) 
     { 
      throw new ArgumentNullException(); 
     } 
    } 
} 

爲了避免陣列創建襲來,你可以有不同數量的參數的個數重載:

public static void CheckNotNull(object x, object y) 
{ 
    if (x == null || y == null) 
    { 
     throw new ArgumentNullException(); 
    } 
} 

// etc 

另一種方法是,以使用屬性聲明參數不應爲空,並且獲得PostSharp以生成相應的檢查:

public void Foo([NotNull] string x, [NotNull] object y, 
       [NotNull] Stream z, int a) 
{ 
    // PostSharp would inject the code here. 
} 

不可否認,我可能希望PostSharp將它轉換爲Code Contracts調用,但我不知道兩者在一起玩的很好。也許一個天我們就可以寫出規格#樣:

public void Foo(string! x, object! y, Stream! z, int a) 
{ 
    // Compiler would generate Code Contracts calls here 
} 

...但不是在不久的將來:)

+0

在你的情況怎麼樣CheckNotNull((對象[])爲null)? :-) – 2009-10-01 12:31:37

+1

認爲作者意味着類似於javascript的參數關鍵字。例如。列出「Foo(string x,object y,Stream z,int a)」方法中的所有參數,並在沒有指定每一個參數的情況下測試它們爲null,但調用一些泛型方法,如「ValidateArgs(Foo.arguments);」 。 – Kamarey 2009-10-01 12:34:09

+0

@Dzmitry:嗯,是的 - 你這個還沒有完全準備好生產:) – 2009-10-01 12:34:30

0

它可以遍歷已申報的方法(通過反射)的參數,但我看不出有什麼辦法來檢索這些參數,具體的方法調用的價值...

也許你可以使用Postsharp,並在執行此檢查的位置創建一個方面。然後,在編譯時,Postsharp可以「編織」方面在每一個你已經寫方法(注入額外的代碼)...

2

您可以定義一個params關鍵字方法參數。這可以將可變長度的參數傳遞給你的方法。然後,您可以遍歷它們並檢查空引用或您想要的任何內容。

public void MyMethod(params object[] parameters) { 
    foreach (var p in parameters) { 
     ... 
    } 
} 

// method call: 
this.MyMethod("foo", "bar", 123, null, new MyClass()); 

在我看來,這不是一個好的做事方式。您將不得不手動控制參數的類型,它們在輸入數組中的位置,並且您將無法在Visual Studio中爲它們使用智能感知。

1

前段時間我有同樣的問題,但是爲了記錄目的,我想這樣做。我從來沒有找到一個好的解決方案,但發現這個鏈接關於使用基於AOP的方法記錄方法條目並退出。它的要點是需要使用一個框架,它可以讀取你的類並在運行時注入代碼來完成你想要做的事情。聽起來不容易。

How do I intercept a method call in C#?

0

提供使用params關鍵字的方法的一個簡單的例子後,RaYell說:

在我看來不過,這不是做事情的好辦法 。您將不得不 手動控制您的 參數的類型,它們在 輸入陣列中的位置,您將無法在Visual Studio Studio中使用intellisense。

我肯定會同意,宣佈接受兩個strings,一個int一種方法,一種object可以爲空,並用params另一個MyClass對象是一個壞主意。然而,(在我看來)完全有效和適當的params關鍵字的應用程序,即當參數都是相同的類型。例如:

public T Max<T>(T x, T y) where T : IComparable<T> { 
    return x.CompareTo(y) > 0 ? x : y; 
} 

public T Max<T>(params T[] values) where T : IComparable<T> { 
    T maxValue = values[0]; 

    for (int i = 1; i < values.Length; i++) { 
     maxValue = Max<T>(maxValue, values[i]); 
    } 

    return maxValue; 
} 
0
var mandatoryFields = (new object[] { input1, input2 }).Where(v => v == null || v.ToString().Trim() == ""); 

你會得到空的參數列表。

,那麼你可以再補充

if(mandatoryFields.ToArray().Count > 0){} 
相關問題