2011-01-05 12 views
5

Code ContractsCode Contracts Editor Extensions VS2010アドインを使用しています。私はIEnumerable<T>インターフェイスを実装するクラスを持っており、GetEnumerator()メソッドのイテレータブロックを実装しました。 GetEnumerator()がnullを返してはいけません、それは副作用を引き起こすことはありませんしなければならない - コード契約:IEnumerator <T> .GetEnumerator()weirdは契約を継承していますか?

ensures result != null ensures result.Model == ((IEnumerable)this).Model [Pure] public IEnumerator(of IBaseMessage) GetEnumerator() {

は、私が第一及び第三の契約要件を理解して:その上、私は次の継承された契約書を見ることができます。しかし、2番目の契約要件は何を意味していますか?この Modelのプロパティは IEnumerator<T>IEnumerableですか?

EDIT:Damien_The_Unbelieverは彼のコメントで指摘したようにIEnumerable<T>IEnumerator<T>のための契約は別々のファイル、契約リファレンスアセンブリに配置されています。エディタで表示されていないGetEnumerator()に追加の契約があります、興味深いことに

[return: Fresh] 
[Escapes(true, false), Pure, GlobalAccess(false)] 
public IEnumerator GetEnumerator() 
{ 
    IEnumerator enumerator; 
    Contract.Ensures((bool) (Contract.Result<IEnumerator>() != null), null, "Contract.Result<IEnumerator>() != null"); 
    Contract.Ensures((bool) (Contract.Result<IEnumerator>().Model == this.Model), null, "Contract.Result<IEnumerator>().Model == this.Model"); 
    Contract.Ensures((bool) (Contract.Result<IEnumerator>().CurrentIndex == -1), null, "Contract.Result<IEnumerator>().CurrentIndex == -1"); 
    return enumerator; 
} 

:(フルコードはhereである)これらの二つのインターフェースの契約の解体で、Reflectorを使用して、以下を参照してくださいすることができます拡張子:

Contract.Result<IEnumerator>().CurrentIndex == -1 

と(例えばFreshEscapesGlobalAccess属性など)いくつかのadditionaly謎。

+1

私はあなたを助けることはできませんが、興味のある分野に向けて私を指摘してくれてありがとう。コードコントラクトで使用される 'IEnumerable'と' IEnumerable'と 'IEnumerable 'タイプは、C:¥Program Files¥Microsoft¥Contracts¥Contracts¥.NETFramework¥v4.0¥mscorlib.Contracts.dll(場所は異なる場合があります)からロードされます。これらのバージョンインタフェース(および関連するコントラクトクラス)には、mscorlibの「実際の」インタフェースより多くのメンバがあります。しかし、契約の注釈を読んでも、私はモデルの目的が何であるか分かりません。 –

+0

@Damien:ありがとう、私は新しい情報ごとに質問を編集しました。 –

+0

その 'IEnumerator'は、実際の' IEnumerator'インタフェースや同じ名前のクラスの型を返しますか?それがインタフェースであれば、なぜそれがコンパイルされるのか理解できません。 – CodesInChaos

答えて

2

C:\ Program Files \ Microsoft \ Contracts \ Contracts.NETFramework \ v4.0 \ mscorlib.Contracts.dllからロードされたコード/コントラクトをもう一度見てきました。

あなたの実装では無視しても問題ないと思います。これは、あなたがIEnumeratorオブジェクトを反復すると(効果的に)一定の数の要素を返すような契約を定義しようとしていることです。これらの要素は、GetEnumeratorの呼び出しが返され、ResetおよびMoveNextの呼び出しが同じ要素のセットに対してのみ反復処理できる場合、効果的に「スナップショット」されます。

私はそれがいくつかの不変性を保証しようとしていると思います。私たちは、同じ種類の契約書を自分たちで書くことができないのかどうかはわかりません。ContractModel属性を使用しています。これはどこにも書かれていないようです。

immutablilityなどに関する

:私は主に返されるのIEnumeratorオブジェクトのMoveNextメソッドのための契約を見ていた

を - 基本的に、我々がした知っていること(MoveNextメソッドは、モデルのプロパティを変更することはできませんと言っていますGetEnumeratorによって割り当てられた同じモデル)、CurrentIndexプロパティは0とModel.Lengthの間で変更されます。それはちょうど直感/推測です。私は何も情報を与えない契約組合の何かを指すことはできません。

+0

私はあなたが契約の解体からどのようにその結論に至ったのかよく分かりません。 [CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)を使用してイテレータブロックを通常のメソッドに変換するとき、これらの追加のプロパティはすべてコンパイラによって生成されますか? –

関連する問題