29

パブリック API がリストを返してはならないという規則に従って、リストを返すすべてのコードを盲目的に変換して、ICollection<T>代わりに返すようにしています。

public IList<T> CommaSeparate(String value) {...}

になる

public ICollection<T> CommaSeparate(String value) {...}

ICollectionにはがありCountますが、そのインデックスでアイテムを取得する方法はありません。

ICollection列挙子を公開しますが (許可foreach)、列挙の順序がリストの「下」ではなく「上」から始まるという保証はありません。

の使用を避けることでこれを軽減しICollection、代わりに次を使用できますCollection

public Collection<T> Commaseparate(String value) {...}

これにより、Items[index]構文を使用できます。

残念ながら、私の内部実装は配列を構築します。orを返すようにキャストできますが、 としてキャストすることはできません。IListICollectionCollection

コレクションのアイテムに順番にアクセスする方法はありますか?

これは、より広い疑問を投げかけます: ICollectionは順序がありますか?


概念的にはコマンド ライン文字列を解析したいとします。アイテムの順序を維持することが重要です。

概念的には、文字列タプルの「順序付けられた」セットを示すコントラクトが必要です。API コントラクトの場合、順序を示すために正しいのは次のうちどれですか。

IEnumerable<String> Grob(string s)

ICollection<String> Grob(string s)

IList<String> Grob(string s)

Collection<String> Grob(string s)

List<String> Grob(string s)
4

9 に答える 9

19

インターフェイスはICollection<T>注文について何も指定しません。オブジェクトは、返されたオブジェクトによって指定された順序になります。たとえば、Valuesa のコレクションを返す場合SortedDictionary、オブジェクトはディクショナリの比較子によって定義された順序になります。

コントラクトによって特定の順序が必要な型を返すメソッドが必要な場合は、より具体的な型を返すことにより、メソッドのシグネチャでそれを表現する必要があります。

返されるオブジェクトの実行時型に関係なく、静的参照がIList<T>orの場合の動作を考慮してICollection<T>ください: GetEnumerator()(おそらく foreach ループで暗黙的に) を呼び出すと、同じメソッドを呼び出して、静的に関係なく同じオブジェクトを取得します。参照のタイプ。したがって、CommaSeparate()メソッドの戻り値の型に関係なく、同じように動作します。

追加の考え:

他の誰かが指摘したように、FXCop ルールは ;List<T>ではなくIList<T>;の使用に対して警告します。IList<T>あなたがリンクした質問は、FXCop がの代わりに使用することを推奨しない理由を尋ねていますがList<T>、これは別の問題です。順序が重要なコマンドライン文字列を解析していると想像するとIList<T>、私があなただったら固執します。

于 2012-01-05T21:44:47.507 に答える
10

ICollection には保証された順序はありませんが、実際にそれを実装するクラスには保証されている (または保証されていない) 場合があります。

順序付けられたコレクションを返したい場合は、IList<T>FxCop の一般的に適切な、しかし非常に一般的なアドバイスに固執しないでください。

于 2012-01-05T21:45:09.527 に答える
4

インスタンスには、それICollectionを実装するクラスの「順序」があります。つまり、aList<T>を an として参照しても、ICollectionその順序はまったく変更されません。

同様に、順序付けされていないコレクションに としてアクセスすると、順序付けさICollectionれていないコレクションにも順序が課されません。

だから、あなたの質問に:

ICollection には順序がありますか?

答えは、それを実装するクラスだけに依存するということです。

于 2012-01-05T21:45:06.717 に答える
4

いいえ、ICollection は順序を意味しません。

于 2012-01-05T21:46:04.417 に答える
3

ICollectionは単なるインターフェースです。順序付けに関する実装や明示的な仕様はありません。つまり、順序付けられた方法で列挙するものを返す場合、消費しているものは何でも順序付けられた方法で返すことを意味しますICollection

順序は、基礎となる実装オブジェクトによってのみ暗示されます。ICollection注文するかどうかという仕様はありません。結果を複数回列挙すると、基になるオブジェクトの列挙子が呼び出されます。これは、これらのルールが設定される唯一の場所です。オブジェクトは、このインターフェイスを継承しているという理由だけで列挙される方法を変更しません。順序付けられた結果であることをインターフェースが指定していれば、実装オブジェクトの順序付けられた結果に安全に依存できます。

于 2012-01-05T21:46:16.007 に答える
3

AnICollection<T>は単なるインターフェースです。順序付けられているかどうかは、その基礎となる実装 (不透明であると想定されている) に完全に依存しています。

インデックスでアクセスできるようにしたい場合は、 と のIList<T>両方であるIEnumerable<T>として物事を返したいと思うでしょうICollection<T>。ただし、基になる実装によっては、コレクション内の任意のアイテムを取得するのに平均で O(N/2) の時間がかかる可能性があることに注意してください。

私の傾向としては、「コレクション」インターフェイスを完全に避け、代わりに、問題ドメインの観点からコレクションを表すカスタム型を使用し、その型に適した適切な論理操作を公開することです。

于 2012-01-05T21:46:32.097 に答える
3

ICollection<T>には順序がある場合がありますが、実際の順序はそれを実装するクラスによって異なります。指定されたインデックスのアイテムのアクセサがありません。IList<T>は、このインターフェイスを特殊化して、インデックスによるアクセスを提供します。

于 2012-01-05T21:46:41.780 に答える
1

インスタンスの実装に依存します。List である ICollection には順序がありますが、Collection である ICollection には順序がありません。

すべての ICollection は IEnumerable を実装します。IEnumerable は、アイテムを一度に 1 つずつ、順序付けされているかどうかに関係なく返します。

編集:質問のコマンドライン解析に関する追加の例に応えて、適切な戻り値の型は、後でそれらの引数を使用して何をしているかに依存すると主張しますが、IEnumerable はおそらく正しいものです。

私の推論は、IList、ICollection、およびそれらの具体的な実装により、Grob から返されたリストの変更が許可されるためです。これはおそらく望ましくありません。.NET には Indexed Sequence インターフェイスがないため、IEnumerable は、返されたパラメーター リストを変更しようとするような奇妙なことを呼び出し元が実行しないようにするための最善の策です。

于 2012-01-05T21:45:30.593 に答える