次のコードを想定します。
[ContractClass(typeof(ICC4Contract))]
public interface ICC4
{
bool IsFooSet { get; }
string Foo { get; }
}
public class CC4 : ICC4
{
private string _foo;
public bool IsFooSet { get { return Foo != null; } }
public string Foo { get { return _foo; } }
}
[ContractClassFor(typeof(ICC4))]
public abstract class ICC4Contract : ICC4
{
public bool IsFooSet
{
get
{
Contract.Ensures((Contract.Result<bool>() && Foo != null)
|| !Contract.Result<bool>());
return false;
}
}
public string Foo
{
get
{
Contract.Ensures((Contract.Result<string>() != null && IsFooSet)
|| !IsFooSet);
return null;
}
}
}
契約は次のように言おうとしています。
IsFooSet
そうでないtrue
場合は戻ります。Foo
null
Foo
null
返された場合IsFooSet
は返されませんtrue
。
これはほとんど機能します。ただし、チェッカーはが常に と等しいことを認識していないため、 に
「証明されていないことを保証します」と表示されます。 return _foo;
Foo
_foo
Foo
セッターを使用して自動プロパティに変更すると、private
その警告が削除されますが、私はそうしたくありません (プライベート セッターを使用した自動プロパティは好きではありません)。
_foo
フィールドを保持しながら警告を消すには、上記のコードで何を変更する必要がありますか?
以下は機能しません。
- の代わり
IsFooSet
に使用するように変更します。で追加の「証明されていない保証」が発生します。_foo
Foo
IsFooSet
- 不変式の追加
Foo == _foo
。これにより、暗黙のデフォルトコンストラクターで「不変の未証明」が発生します。さらに、実際のコードベースでは、静的チェッカーの処理時間は大幅に長くなります。 - この回答に従って
Contract.Ensures(Contract.Result<string>() == _foo);
のゲッターに追加しても、何も変わりません。Foo