1

Contains の複数の呼び出しが同じ enumerable の同じパラメーターに対して異なる値を返す理由を理解できません。コレクションを変更して、後続の呼び出しで結果を変更できることは理解していますが、ここでは除外できます。

MVC ビューで次の (簡略化された) コードを検討してください。これの目的は、チェックボックスのリストを表示し (そのための HTML ヘルパーがないため)、ビューを開くときにチェックする必要があるモデルのプロパティを決定することです。

@foreach (var d in Model.AllDomains) {
    bool isChecked = Model.Project.Domains.Contains(d.ID);
    <input @(isChecked ? "checked=\"checked\" " : "")type="checkbox" value="@d.ID" />
    // more stuff here
}

これを実際のリストを使用するように変更すると、すべてが期待どおりに機能します。

var tmp = Model.Project.Domains.ToList();
@foreach (var d in Model.AllDomains) {
    bool isChecked = tmp.Contains(d.ID);
    <input @(isChecked ? "checked=\"checked\" " : "")type="checkbox" value="@d.ID" />
    // more stuff here
}

以下は、私のビューにバインドされているモデルです (読みやすくするために単純化されています)。

public ProjectVM GetByID(int id) {
    return new ProjectVM {
        Project = new Project {
            ... // Other properties here
            Domains = from d in MyObjectModel.Projects[id].Domains
                      select d.ID
        },
        AllDomains = from d in MyObjectModel.Domains
                     orderby d.Name
                     select new {
                         ID = d.ID,
                         Name = d.Name
                     }
    };
}

さて、デバッグからModel.Project.Domains、正しい値だけでなく正しい数のエントリが含まれることがわかっていますが、メソッドで .Contains() を呼び出すと、true または false のいずれかの任意の結果が返されます。

実際、Contains() 呼び出しを含む行をデバッガーの [ウォッチ] タブに複数回配置すると、ハードコードされた引数 (4 など)を使用しても、呼び出しごとに結果が交互trueに変わります。false

ここで何が起こっているのか、私は何を見落としているのでしょうか?

Model.Project.Domains がインスタンス化される方法のため、その実際の型は aWhereSelectEnumerableIterator<T>ですが、これは実装されIEnumerable<T>ているため、問題になることはありません...

4

1 に答える 1

1

GetEnumerator()問題の根本的な原因は、以前の呼び出しで既に使用されていたイテレータを返す、オブジェクト モデルの基礎クラスでの Enumerator のずさんな/異常な実装だったようです。

最初の一致が見つかった後にコレクションの反復を停止するためContains()、シークされた値が前の反復で既に検索された部分にある場合、そのような列挙子では false が返されます。の否定的な結果Contains()により、列挙子が内部的にリセットされ、元の投稿で説明した「トグル」の結果が説明されました。

于 2013-07-23T06:30:36.783 に答える