2009-05-02 10 views
13

私は最近、IList上で強く型付けされた配列を返すことを好んだ理由を誰かに尋ねていました。私はいつも、インターフェイスに対するプログラミングは、長い寿命を持つプロジェクトに直面したとき、最も柔軟で最良の方法であると考えていました。だから、私が奇妙に思ったのは、彼が答えたときでした。IListを返す<T> vs Array in C#?

通常、変更可能なタイプよりも不変のタイプ が優先されます。配列は 不変です。 IListはそうではありません。

私はこの声明をよく理解していません。誰でもこれを明確にするのに役立つことができますか

ご協力いただきありがとうございます。

答えて

10

配列の長さプロパティが不変なので何とか思っていたと思うのですが、配列はです。はIListよりも不変ですか、間違った単語を使用し、誰が知っているが、それは奇妙な答えです。

リストを返すと、それを修正しても構わないとか、配列を返す間に変更されるかもしれないということが少しは暗示されていると思います。

例えば、リポジトリの上にオブジェクトモデルがあり、GetCars()のようなメソッドがあり、Listを返して、ジュニアプログラマがcars.Add(Car c)を見たとします。思考のcars.Add(新車())実際には、レポジトリに車を追加する可能性が完全に狂った?配列は本質的により明示的です。

は、私はいくつかの理由で帰国配列よりも頻繁一覧を好む

Page.Controls.Add

のようなリストの使用量は、性質がより適切であると思います。

  • 習慣。 1.0/1.1のコレクションSUCKED

  • 私のメソッドは、もっとも軽量のオブジェクトである最も簡単な&を返すことをお勧めします。配列をリストにする必要がある場合、それは簡単です。

  • .net 1.1で使用することができ、以前のバージョンのランタイムをサポートする必要がある場合は、リファクタリングのサーフェスを削減します。コードの一部を再利用するか、同一のオブジェクトモデルを適用できます。

+0

これは、私が探していた「ああは」の瞬間を私に与えました!リポジトリからT []を返すことは、「リーキーアブストラクションの法則」のように、「漏れ」ではありません。私がリポジトリに何かを追加したいのであれば、それはAdd/Insertメソッドなのでしょうか?返されたリストに何かを追加すると、作業ユニットに参加したり、予想どおりに働くことができると仮定することは、逆効果的/直感的ではありません。 IRepositoryを使用する場合、彼は100%正しいです!彼が私に与えた説明は、あなたが言ったことの線に沿っていましたが、配列はIListよりも不変です。どうもありがとうございます! – mkelley33

+2

+1ジュニアを見るリスト .Addは良いアイデアだと思うかもしれません。 –

1

おそらく、この誰かが彼が話していることを知りませんか?

+1

私はそれを疑う。それは、私が "彼が"笑いについて何を話しているかわからない可能性が高いです。 – mkelley33

0

基本的に彼は、「私たちは、実行時に簡単に変更できない構造を好んでいます。なぜなら、エラーに対して脆弱ではないと信じているからです。この場合正しいかどうかは別の問題です。

+0

Hmmm。私はそれが好きですが、私は実装よりも柔軟性があるので、IList に対してプログラミングするよりも、その価値があるかどうかわかりません。助けてくれてありがとう。それは彼の立場を少しはっきりさせます。 – mkelley33

2

どちらも分かりません。配列は、サイズを除いて、非常に変更可能です。個々の要素は変更することができます。おそらく、配列が値型であり、リストが参照型であることを意味します。知りません。

とにかく、件名にEric Lippert's opinionがあるはずです。議論のためのいくつかの弾薬を提供することができます。

+0

ありがとうございます。私はその記事を読んだので、混乱は笑う。変更可能性の主題に関する様々な意見があれば、私は自分の腸の本能に行き、IList を返す必要があります。私は、この質問の記述で引用文を提供した人に私が完全に借金していると言っています。 「尊敬の念を抱く者」は素晴らしいコーダーとインスピレーションですが、私は盲目的にフォローしていませんので、ここで提供された議論に反論するまで待たなければなりません!再度、感謝します。 – mkelley33

+0

あなた自身のために考えて、良い! :)あなたの友人を説得して幸運。 – Rik

7

IListにはInsert、Remove、およびAddメソッドが含まれているため、コレクション自体を変更することができます。一方、T []は要素を追加することはできません。

FxCopでは、代わりにReadOnlyCollectionを返すことを推奨します。インデクサーは読み取り専用なので、要素を変更することはできず、AddメソッドなどのメソッドはすべてNotSupportedExceptionをスローします。

+1

クール!それは素晴らしいことです。私は自分の仕事でFxCopを使用しています。私はいつもその推奨事項のいくつかについて疑問を抱いています。解明してくれてありがとう! – mkelley33

+1

トップの近くにある最短の短い答えのために+1 –

0

おそらく、彼は配列のサイズを「不変」と定義していたでしょうか? 基本的には、サイズを一度宣言すると、そのサイズに固執します。リストを使うと、いつでも "Add"を使うことができます。

私は、おそらく配列が少し速くなる場合は、リストのサイズについて確認していますと仮定

+0

これはまさに私が想定したものですが、リポジトリパターンを使って作業するときに私が買うものは本当にわかりません。ありがとう! – mkelley33

0

IListは、既に存在するアイテムを変更するのではなく、アイテムを追加したり削除したりできるという意味では変更可能です。配列は個々のアイテムを混乱させるが、特定のインデックスは決して完全に無効になることはない。不変性を好むいくつかの理由があります - 例えば、偶発的なデータ破損の表面積をはるかに小さくします。

+0

ICollection を使用し、1つを返すと読み取り専用のものを返します。配列はこのインタフェースを実装しているので、インタフェースやリストをそのようなメソッドに渡すことができます。カウント、追加と削除は汎用ICollection インターフェイスで定義されています。 – Lucero

12

"彼"が誰であれ、トピックに100%間違っています。配列は非常に変更可能です。これは実際に配列を返さない理由の1つです。呼び出し元が配列の要素を変更しないようにする方法はありません。

Arrrayが不変である唯一の方法は、その長さです。配列が割り当てられたら、その長さは変更できません。 Array.ResizeのようなAPIでさえも、配列のサイズを実際には変更しないで、新しいものを割り当て、内容をコピーして新しい配列を返します(この例では参照)。

しかし、不変のデータを返す方が良い場合が多いことに同意します。主な目的は、完全なコピーを行うことなくクラスの内部コレクションへの参照を返すことができると同時に、呼び出し側が内部状態を乱さないようにすることです。ほとんどの変更可能なコレクションは、そのような保証をすることはできません。原則として

+2

"それは有効です.." - それはより良い "という意味ですか? – peterchen

+1

@peterchen、そうです、それは私が言いたいことです。 – JaredPar

+0

まあ、私はそれほど遠くに行くことはないだろう... "彼は本当に素晴らしいコーダーだが、彼は以下のコメントの1つで何らかの側面を指していると思う。しかし、私はこれが私または私のプログラムを "買う"ものを見ていない。オブジェクトのリストを返すためにリポジトリパターンを使用している場合、なぜIListではなく配列でなければならないのですか?? – mkelley33

5

彼は右だが、彼はそれを正しく実践する方法を知りません...

は、我々は一般的に変更可能なものの上に 不変のタイプを好みます。

これは間違いありません。変更不可能な型は、使用するにはより良いです

配列が不変です。 IListはそうではありません。

これは間違っています。どちらも不変です。

不変のコレクションを返す場合は、IEnumerable<T>またはReadOnlyCollection<T>List<T>.AsReadOnlyメソッドを使用)を返します。それでも、オブジェクト自体が不変でない場合、それらはオブジェクトを保護しません。コレクションから読み取ることはできますが、許可しても各オブジェクトのデータは変更できます。

また、返すコレクションの「所有権」も考慮する必要があります。それを返す唯一の目的のために配列を作成しているなら、それを完全に制御しない理由はありません。一方、クラスのメンバーであるコレクションを返す場合は、必要なときにアクセスできるようにする必要があります。

1

インタフェースを実際の型自体に対してリターン型として使用する理由は、内部実装を呼び出し元から隠すためです。これにより、インプリメンテーションは、アプリケーションの残りの部分に再利用なしに実際のタイプを変更することができます。

内部で使用されているコレクションを、外部で使用するために、可変または不変以外の理由でコピーするのは意味がありません。

個別の問題は次のとおりです。 - 厳密に型指定されたデータのリストを返します。 IListまたはIList。 強く型付けされたデータの使用が常に優先されます。 - 変更可能または不変です。 ICollection、IListまたはIEnumerator データに許可したいものを返します。読み取り専用リストの場合は、IEnumeratorのみを返します。呼び出し元がコレクションを変更できる場合は、ICollectionまたはIListを使用します。

8

私はいつもReadOnlyCollectionを好んでいます。リストのすべての利点が、読み取り専用です。