2015-02-24 19 views
3

我想強制我的方法只接受整數參數,如果它是正數。如果該方法通過一個整數它應該會引發編譯時錯誤。達到此目的的最佳方法是什麼?強制C#方法只傳遞正參數?

目前我正在使用Math.Abs(Int)裏面的方法,但我想錯誤是在編譯時。

+0

從理論上講,你可以使用unsigned int,但在實踐中這並沒有多大幫助。 – CodesInChaos 2015-02-24 15:17:29

+0

你似乎認爲每個數字都是正數或負數。什麼是零? – hvd 2015-02-24 15:17:36

+1

你不能爲參數拋出一個編譯時錯誤,就編譯器知道的任何錯誤而言。 – 2015-02-24 15:17:40

回答

14

只需設置參數a uintushort。這將防止編譯時的負面輸入。它不會阻止0,但是......我假設你真的是在非負面輸入之後,而不是嚴格正面的輸入。

如果你的方法接受簽名的參數,然後:

  • 您可以驗證參數值,拋出一個異常,如果它是無效的。 (這比使用Math.Abs嘗試「修理」無效的輸入更好的主意。)
  • 你可以使用Code Contracts來指示該參數應該有一個非負值其他代碼,它會嘗試證明無處不在你稱之爲方法,價值將是非負面的。這不會被C#編譯器強制執行,但它仍然可以是構建時過程。

如果用異常的方法去的話,你應該也有周圍的代碼調用你的方法一組全面的單元測試 - 這代碼應該驗證輸入,以及,當然。

+0

@Tigran它會使運行時永遠不可能有無效的值;它將確保對這些值進行靜態檢查,以確保它們始終有效。 – Servy 2015-02-24 15:19:26

+3

@Tigran當然會的。給定'void f(uint x)',它會使'f(-1)'出錯,並允許'f(0)'和'f(1)'。 – hvd 2015-02-24 15:19:51

1

您可以使用Code Contracts(和link),並在編譯之前做一個靜態代碼分析,然後使用:

Contract.Requires(parameter >= 0); 

靜態代碼分析是有限的,你不應當限制對代碼合同(你還是應該扔掉運行時異常)。它會捕獲顯而易見的東西(比如傳遞常量),但當它們來自代碼外部時(從磁盤讀取數據庫或其他東西),不會捕獲負值的傳遞。

這在編譯時是不可能的

+0

我的*非常有限的回憶是代碼合約*可以*捕獲傳遞負值,當它們來自您的代碼之外時,但它通過投訴,如果您不驗證輸入(在驗證之後使用'Contract.Ensures' )。 – Brian 2015-02-24 17:34:31

+0

@布萊恩是的,代碼合同也可以做運行時檢查,我說的時候我說的是「靜態代碼分析」...現在我讀了它可能錯誤地表達了它 – Jcl 2015-02-24 17:39:30

+1

不,我也在談論靜態代碼分析。它會靜態捕獲來自代碼外部的傳遞負值,如果任何函數接受來自代碼之外的值而不包含後置條件(通常使用'Contract.Ensures',儘管我相信Contracts分析器能夠理解簡單的條件,所以明確的後置條件可能是不必要的。正確使用,這足以迫使c-sharp方法只傳遞正面參數(承認這只是將問題轉移到其他地方,但它仍然是一個維護勝利)。 – Brian 2015-02-24 21:29:11