2012-10-13 56 views
0

假設我有以下代碼:Code Contracts:模板方法模式超類的不變量不起作用?

public abstract class TemplateBase { 
    public void TemplateMethod() { 
     Operation(); } 

    protected abstract void Operation(); } 

public sealed class Implementation : TemplateBase { 
    bool _alwaysTrue; 

    public Implementation(bool alwaysTrue) { 
     _alwaysTrue = alwaysTrue; } 

    [ContractInvariantMethod] void ObjectInvariant() { 
     Contract.Invariant(_alwaysTrue == true); } 


    protected override void Operation() { 
     _alwaysTrue = false; } } 

[TestClass] public sealed class InvariantTest { 
    [TestMethod] public void Constructor() { 
     new Implementation(false); } 

    [TestMethod] public void Method() { 
     new Implementation(true).TemplateMethod(); } } 

InvariantTest.Constructor總是失敗與「不變失敗」例外。

如何根據不變量獲取InvariantTest.Method失敗?

我已經將運行時檢查設置爲完整,甚至啓用了「呼叫站點需要檢查」,但即使這也沒有幫助。

+0

當直接調用基本方法時,運行時僅檢查該類及其基類中的不變量。沒有虛擬不變的調用完成。結果,派生的不變量不被檢查。爲了執行該檢查,您需要重寫TemplateMethod並在那裏調用基本方法。這將檢查支票。一般來說,你的模式很難完全安全,因爲你需要派生類來控制所有入口點。 –

回答

0

如果您使用最新版本(1.4.50910.0),您將從靜態檢查器得到一個警告,說明不變量是錯誤的。

但是對於運行時,這是預期的行爲。從manual

在運行時檢查,不變量 在每個公共方法結束時檢查。

爲了達到目標不變量的目的,被保護的覆蓋可能被認爲是「公共」。您可能想開始討論Code Contracts forum