web-dev-qa-db-ja.com

インスタンス化されたときにICollectionインデックスが機能しないのはなぜですか?

パラメータをICollectionとして宣言し、オブジェクトをListとしてインスタンス化した場合、なぜインデックスを取得できないのでしょうか。つまり.

_ICollection<ProductDTO> Products = new List<ProductDTO>();
Products.Add(new ProductDTO(1,"Pen"));
Products.Add(new ProductDTO(2,"Notebook"));_

次に、これは機能しません:

ProductDTO product = (ProductDTO)Products[0];

私が欠けているビットは何ですか?
[はい、リストを宣言として使用できますが、次のようにリストとして宣言したくありません。

List<ProductDTO> Products = new List<ProductDTO>();

]

20
demokritos

ICollection インターフェイスはインデクサーを宣言していないため、インデックスを使用して、そのタイプの参照を介して要素をフェッチすることはできません。

IList を試してみてください。これにより、抽象的でありながら、いくつかの機能が追加されます。もちろん、これは他の設計上の決定に影響を与える可能性があるので、これを注意深く検討します。

28
Chris W. Rea

LINQを使用すると、次のことができます。

ProductDTO product = (ProductDTO)Products.ElementAt(0);
33
jeremcc

ICollectionはインデクサーを定義しません。

ICollection Non-Generic

ICollection Generic

7
ChaosPandion

その後、これは機能します:

ProductDTO product = ((IList<ProductDTO>)Products)[0];

その理由は、コンパイラがlvalue、つまり '='の左側にある変数を評価して、アクセスできるメソッドとプロパティを見つけるためですknowsコンパイル時。これは静的型付けと呼ばれ、メンバーが常に到達可能であることを静的に認識することにより、実行時にオブジェクトメンバーに直接アクセスできるようにします。

5

基本的な問題は、ICollectionがインデックスを定義しないことです。リストの場合、これはIListの実装によって行われます。

これを試して:

IList<ProductDTO> Products = new List<ProductDTO>(); 

または、インデックスで要素にアクセスする必要がある場合は、ICollectionを引き続き使用し、配列に変換できます。

ICollection<ProductDTO> Products = new List<ProductDTO>();        
ProductDTO z = Products.ToArray()[0];
3
Stephen M. Redd

Linqを使用すると、次のような特定のインデックスにあるICollection <>の要素にアクセスできます。

myICollection.AsEnumerable().ElementAt(myIndex);
2
NoRelect

拡張メソッドを使用して、それをProductDTOの(リスト、配列)に変換することもできます。

ICollection<ProductDTO> Products = new List<ProductDTO>();
var productsList = Products.ToList();

次に、次のように使用できます。

productsList[index]
0
Qais Bsharat