2

多くのメソッドを持つクラスと、それに対応するプロパティを持つ _isLoaded というプライベートな読み取り専用ブール フィールドがあります: public bool IsLoaded:

class MyClass
{
    readonly bool _isLoaded;
    public bool IsLoaded
    {
        get { return _isLoaded; }
    }

    public void Method1()
    {
        //does whatever
    }

    public void Method2()
    {
        //does another thing
    }

    public void Load()
    {
        //does a lot of things and then...
        _isLoaded = true;
    }
}

パブリック メソッドを呼び出した後でも、特定のオブジェクトが一貫した状態のままであることを保証するオブジェクト不変メソッドがあることを私は知っています。たとえば、これをクラスに追加した場合:

[ContractInvariantMethod]
void checkState()
{
    Contract.Invariant(!_isLoaded);
}

今、私の問題は次のとおりです。1 つの特定のパブリック メソッド (私の場合は Load) に対してのみ ContractInvariantMethod で注釈が付けられたメソッドを呼び出さないようにランタイムに指示する方法はありますか?私の畑の状態?

(または、同じ目的を達成するための他の方法)

ありがとう。

編集:
@Liel
答えてくれてありがとう!
このパターンは、考慮すべきフィールドが 1 つしかない場合に完全に機能します。この契約の事後条件も追加しました。

public abstract class BaseMyClass
{
    private bool _isLoaded;
    public bool IsLoaded
    {
        get { return _isLoaded; }
    }
    public virtual void Load()
    {
        Contract.Ensures(IsLoaded);
        _isLoaded = true;
    }
}

public class MyClass : BaseMyClass
{
    public override void Load()
    {
        //does a lot of things and then...
        base.Load();
    }
}

base.Load()残念ながら、静的チェッカーは事後条件を満たすために呼び出さなければならないことを理解できるほどスマートではありません。Contract.Assume(IsLoaded)どうやら、静的チェッカーは完璧にはほど遠いようです。

4

2 に答える 2

1

あなたが達成したいことを理解していれば、Contract.OldValue() コンストラクトを使用できます。

public class MyClass
{
    bool _isLoaded;

    public bool IsLoaded
    {
        get { return _isLoaded; }
    }

    public void Method1()
    {
        Contract.Ensures(this._isLoaded == Contract.OldValue(this._isLoaded));
        //does whatever
        _isLoaded = false;
    }

    public void Method2()
    {
        Contract.Ensures(this._isLoaded == Contract.OldValue(this._isLoaded));
        //does another thing
    }

    public void Load()
    {
        //does a lot of things and then...
        _isLoaded = true;
    }
}

これをコンパイルすると、次の警告が表示されます。

CodeContracts: ensures unproven: this._isLoaded == Contract.OldValue(this._isLoaded)
于 2013-07-01T07:36:38.993 に答える
0

次のアプローチを試すことができます。

public class BaseMyClass
{
    private bool _isLoaded;
    public bool IsLoaded
    {
        get { return _isLoaded; }
    }
    public virtual void Load()
    {
        _isLoaded = true;
    }
}

public class MyClass : BaseMyClass
{
    public void Method1()
    {
        //does whatever
    }

    public override void Load()
    {
        //does a lot of things and then...
        base.Load();
    }
}

IsLoadedこの方法でからアクセスでき、オーバーライドMyClassのみがプロパティを変更していることを確認できます。Load_isLoaded

于 2013-06-30T07:02:47.117 に答える