2012-01-03 79 views
2

前幾天我問了一個問題,標題爲How to constraint a generic to be of type enum?。總結問題是下面的代碼:使用代碼合同來使通用類型枚舉

class MyClass<T> where T : enum // Not possible in C# 
{ 
} 

我被介紹給代碼合同,我可能會產生一個編譯時間問題,這是所有我想警告(在編譯時被告知T應是enum)。我嘗試了以下代碼(Full source)。

class MyClass<T> 
{ 
    public MyClass() 
    { 
    Contract.Requires(typeof(System.Enum).IsAssignableFrom(typeof(T))); 
    } 
} 

它只會產生無用的運行時錯誤。我應該能夠產生編譯時警告,但我不能讓它工作。誰能告訴我我做錯了什麼?

這裏的項目的代碼契約設定的畫面: Code Contracts Setting

+0

您是否使用該問題的接受答案中提出的庫? – Oded 2012-01-03 18:19:10

+0

@Oded,我試過了,但沒有示例代碼,所以我甚至不知道從哪裏開始。雖然這是另一個問題,但我發現這是一個更好的方法,因爲它已經是.NET框架的一部分。 – atoMerz 2012-01-03 18:21:25

+1

@AtoMerZ:Unconstrained Melody旨在用作庫,但您可以對自己的代碼使用相同的IL重寫。只需看看代碼 - 它非常簡單。 – 2012-01-03 18:23:12

回答

1

所以,我寫了下面的代碼放在一個文件:

public class SomeClass<T> 
{ 
    [ContractInvariantMethod] 
    private void Invariants() 
    { 
     Contract.Invariant(typeof(System.Enum).IsAssignableFrom(typeof(T))); 
    } 

    /// <summary>Initializes a new instance of the SomeClass class.</summary> 
    /// <param name="dependency"></param> 
    public SomeClass() 
    { 

    } 
} 

public class SomeOtherClass 
{ 
    public SomeOtherClass() 
    { 
     var myClass = new SomeClass<int>(); 

    } 
} 

從那裏,我走進了代碼契約項目的節選項,並選中「靜態檢查」下的所有複選框。然後我將警告級別設置爲「高」。當我重建解決方案時,我收到一條警告:「代碼合同:不變要求未經證實:typeof(...)」與類不變相對應。

從那裏,我設置警告級別降低,並看到沒有警告,ala你正在報告。所以,我認爲將警戒級別設置爲高是你需要的。如果這不起作用,你可以嘗試遵循我所做的事情,並將你的合約定義爲一個類不變量(這在我的經驗上,我會建議做,因爲這在概念上更像是一個類層次不變的概念,而不是你的構造函數執行的結果)。

編輯:我發佈後看到你的截圖,所以我會修改這個建議使用我的「如果這不起作用」建議與類級別不變而不是需要從xtor調用。

+0

謝謝。它在兩種方式下工作(先決條件和不變)。我不確定錯誤是什麼,但我注意到編譯後警告花了幾秒鐘,所以我認爲我只是不耐煩。 – atoMerz 2012-01-03 19:04:47

+1

默認是在後臺運行靜態檢查,所以在編譯完成後它會繼續運行。當項目變得更大時,這變得很重要,因爲如果沒有它,靜態分析將花費很長時間。如果需要,您可以通過取消選中「檢入背景」來繞過此項,對於較小的項目。 – 2012-01-03 19:06:26