2012-04-03 72 views
1

我在實現靜態輔助類,類似的NUnit的Assert一個非常簡單的「契約式設計」的早期過程很。理想情況下,我期望做的是傳遞一個表達式,檢查它是否爲真,如果不是,則拋出具有任何參數或錯誤消息的特定異常。 在一個理想的世界我會做這樣的事情:契約式設計,和一般例外

// ideal 
Assert.True<ArgumentNullException>(user != null, "User", "User cannot be null"); 

// not so ideal 
Assert.True(user != null, new ArgumentNullException("User", "User cannot be null"); 

現在,我的問題是,在Assert.True<T>的約束是Exception, new(),爲了讓我來創建所需類型的新的異常。我現在遇到的關鍵問題是,首先通用構造不允許參數,其次,在Exception構造最屬性僅是GET。

任何幫助是極大的讚賞,謝謝。

回答

0

謝謝你的答案;我發現有輕微的工作圍繞在System.Activator.CreateInstance的形式,這是在一個非常類似的帖子討論在這裏找到:Casting Exceptions in C#

throw (T) System.Activator.CreateInstance(typeof(T), message, innerException); 
1

怎麼是這樣的:

Assert.True(user != null,() => new ArgumentNullException("User", "User cannot be null"); 

通過委派異常的實例化一個匿名方法,你只構造異常,當你需要它。這也可以解決您在Assert類中實例化異常的問題。

Assert.True然後可以是這個樣子:

public static True(bool condition, Action<Exception> exception) 
{ 
    if(!condition) throw exception(); 
} 
+0

嗯,這是一個非常優雅的解決方案,我喜歡它,但理想的我爲了可讀性。謝謝你! – Richard 2012-04-03 10:56:57

+0

嘿,是啊,這不是你的「不理想」的情況了大規模的改進,但我不認爲你可以得到沒有一些重大的黑客/巫術更接近。 – mdm 2012-04-03 11:04:10

+0

@Richard,以提高可讀性,你可以添加一堆的常見場景輔助方法(如參數空/無效等),例如'ArgAssert.NotNull(用戶, 「用戶」)'或'ArgAssert.Valid(用戶!= NULL, 「用戶」)'! – VinayC 2012-04-03 11:06:06

2

我敢肯定你已經知道微軟的代碼契約的支持,但如果你不是(並因此在不知不覺中重新發明輪子)你可以在這裏找到它們:

http://research.microsoft.com/en-us/projects/contracts/

+0

代碼合同的問題是您必須使用工具激活它們。沒有激活它,異常不會被拋出。因此,在現有的代碼庫上使用並不容易。 – danfromisrael 2012-04-04 06:37:27