9

私は不変の辞書の特別なケースを実装していますが、これは便宜上IEnumerable<KeyValuePair<Foo, Bar>>. 通常ディクショナリを変更する操作は、代わりに新しいインスタンスを返す必要があります。

ここまでは順調ですね。しかし、クラスの流暢なスタイルの単体テストを作成しようとすると、私が試した 2 つの流暢なアサーション ライブラリ ( ShouldFluent AssertionsNotBeSameAs() ) のどちらも、実装するオブジェクトの操作をサポートしていIEnumerableないことがわかりました。それらにObject

私が最初にこれに遭遇したとき、Should で、それはフレームワークの単なる穴だと思いましたが、Fluent Assertions に同じ穴があるのを見て、そう思いました (私は C# に比較的慣れていないため)。 C# コレクションに関する概念的な何かが欠けている可能性があります

明らかに、これをテストする他の方法があります-キャストしObjectて使用するNotBeSameAs()、単に使用するObject.ReferenceEqualsなど-しかし、そうしない正当な理由がある場合は、それが何であるかを知りたいです。

4

2 に答える 2

1

AnIEnumerable<T>は必ずしも実際のオブジェクトではありません。IEnumerable<T>状態を列挙できることを保証します。List<T>単純なケースでは、すでに実体化されているのようなコンテナクラスがあります。次に、両方のリストのアドレスを比較できます。ただし、IEnumerable<T>列挙すると実行される一連のコマンドを指す場合もあります。基本的にステートマシン:

public IEnumerable<int> GetInts()
{
    yield return 10;
    yield return 20;
    yield return 30;
}

これを変数に保存すると、同等のオブジェクトがなくなります(すべてがオブジェクトなので、そうします...しかし、意味がありません)。

var x = GetInts();

これらのステートマシンが評価され、その結果がコレクションに保存されているため、比較はマテリアライズド(.ToList()または)IEnumerablesに対してのみ機能します。.ToArray()そうです、ライブラリは実際に意味があります。IEnumerablesを実体化したことがわかっている場合は、それらをObjectにキャストし、このオブジェクトで目的の関数を「手動で」呼び出すことによって、この知識を公開する必要があります。

于 2013-03-13T16:24:48.573 に答える
1

さらに、Jon Skeet が提案したことは、2013 年 2 月の Ted Neward による MSDN の記事を参照してください。

.NET コレクション、パート 2: C5 の操作

不変 (保護された) コレクション

関数型の概念とプログラミング スタイルの台頭に伴い、不変データと不変オブジェクトに重点が置かれるようになりました。これは主に、不変オブジェクトが同時実行性と並列プログラミングに対して多くの利点を提供するためだけでなく、多くの開発者が不変オブジェクトを見つけているためでもあります。理解しやすく、推論しやすくなります。その概念の当然の帰結として、不変コレクションの概念が続きます。これは、コレクション内のオブジェクトが不変であるかどうかに関係なく、コレクション自体は固定されており、コレクション内の要素を変更 (追加または削除) できないという考えです。(注: MSDN ベース クラス ライブラリ (BCL) ブログ ( bit.ly/12AXD78 ) で、NuGet でリリースされた不変コレクションのプレビューを確認できます。)

C5 と呼ばれる優れたコレクションのオープン ソース ライブラリの使用について説明します。http://itu.dk/research/c5/を見てください

于 2013-03-13T16:44:57.043 に答える