2017-01-08 6 views
2

多くの場合、配列を受け入れるメソッドを提供すると、IEnumerableであり、CountまたはLengthを必要とするより一般的なクラスを受け入れるように最適化することができます。提供するパラメータタイプは、IEnumerableでCountがありますか?

例:ここでは

public static T NextObject<T>(this Random random, T[] array) 
{ 
    return array[random.Next(array.Length)]; 
} 

、私は元素の量を知って、特定の要素を取得するためにArrayを使用しています。どのクラスが一般的な方法でこれに最適ですか?

  • のIList
  • いるICollection - もCount
  • 他のインターフェースまたはクラスまたは異なるインターフェースのセットを有しますか?

私は、根本的な列挙は、より複雑な場合Count()は、パフォーマンス上の副作用を引き起こす可能性があるので、IEnumerableは、良いアイデアではないかもしれないと思う

+0

私は 'ICollection 'を使うことをお勧めしますが、私はそれが少し意見*に基づいていると思います。 – MarcinJuraszek

+0

'ICollection 'にはインデクサーがありません。私は、この2つのオーバーロードとしての「配列」は、すべての型をカバーする*(わからない)と考えています。私はこれが意見に基づくとは考えていません。なぜなら、質問は基本的にすべての一般的なタイプを最低限のオーバーロードでカバーしているからです。 – bytecode77

+0

なぜ単純なリストではない? –

答えて

2

コレクションのアイテムのインデックスと数でアイテムにアクセスする必要があります。また、コレクション/インターフェイスの追加メンバーが少なくて済むようになります。

     | IList<T> | ICollection<T> | IEnumerable<T> | T[] 
Access by index  |  + |  -  |  -  | + 
Count of items  |  + |  +  |  -  | + 
Less unwanted members |  - |  +  |  +  | ~ 

ご覧のとおり、ICollectionとIEnumerableはあなたのニーズに合っていません。私はIListまたは配列をピックするのに大きな違いは見られません。 IListはおそらく配列よりも軽いかもしれませんが、多くの望ましくない操作(Add、Remove、Clear)があり、配列でparamsを使用すると便利です。

+0

非常に優れた視覚化!おそらく、配列とIListの両方でオーバーロードを提供するのが最善でしょう...しかし、コードが例よりも複雑な場合はどうなりますか?配列を提供し、消費メソッドに '.ToArray'を必要としますか? – bytecode77

+0

@ bytecode77おそらく 'IList 'と 'params T []'を使った2つのオーバーロードが最も便利です: 'ranomd.NextObject(apple、banana、peach)' –

0

あなたのメソッドは、メソッドのニーズを満たす少なくとも特定の型を取る必要があります。可能な限り少ないカップリングを目指してください。ここではどちらICollection<T>IEnumerable<T>サポートインデックス以来ICollection

public interface ICollection<T> : IEnumerable<T>, IEnumerable 

ための署名があり、そのどれも動作しません。

配列はあまりにも具体的ですが、インデックスでアクセスする必要があるため、List<T>またはIList<T>がニーズを満たします。それ以外の場合、クライアント(クラスのコンシューマ)は配列型にキャストする必要があります。

しかし、カウントが

Count()System.Linq.Enumerableの拡張メソッドであるパフォーマンス上の副作用を引き起こす可能性があります。 ICollection(Countプロパティ)のようなO(1)カウントをサポートする型にキャストしようとします。どれも利用できない場合、それはすべてのアイテムをトラバースし、それらをカウントしてO(N)になる。

+0

もし私が間違っていなければ、それは 'IEnumerable 'を実装するすべての*コレクションクラスさえあります。しかし、それはランダムアクセスをサポートしておらず、 '.Skip'を使用することは性能上決定できないコンパクトであるため、IEnumerableは使用できません。 – bytecode77

+0

@ bytecode77申し訳ありませんあなたの質問は数と長さでしたが、あなたのコードではランダムなインデックスが必要です。答えを編集しました。 – CodingYoshi

関連する問題