2013-11-22 19 views
5

これは、(C++の逆に)C#で、C#のIListコレクション私の知る限りでは オブジェクトの割り当ては

IList<MyClass> foo = new List<MyClass>(); 
var bar = new List<MyClass>(); 

foo.AddRange() // doesn't compile 
bar.AddRange() // compile 

を使用している間、私が遭遇したものですオブジェクト型は、左辺(宣言)ではなく右辺(代入)を取得します。

ここに何か恋しいですか?

EDIT

私はまだあなたの答え、fooとbarが同じ型を持っていた後でも、それを得ることはありません! enter image description here

+2

"var"は "AddRange"メソッドを持つタイプリストですが、fooは "AddRange"メソッドを持たないインターフェイスであるIList タイプです。 – sjkm

+0

しかし、両方とも型Listでインスタンス化されます。

+0

@Schneiderそれは本当ですが、コンパイラの観点からは、 'foo'の型は' List <> 'ではなく' IList <> 'です – rhughes

答えて

18

ここで起こっので、微妙なものは何もありません:

  • fooがタイプIList<MyClass>IList<T>
  • バータイプList<MyClass>List<T>は、AddRangeメソッドを持っている持ってAddRangeメソッドを持っていない持っています。

これだけです。これはC++でも同じです。

更新:さらに、オブジェクトの実行時の型を取得するGetType()を呼び出しています。コンパイル時にコンパイラはfooおよびbar変数の静的型を見ています。

彼らは同じ継承のIListとして関係してリストを持っているにもかかわらず、「オブジェクト」と「文字列」の間のより明確な差がありますので程度Object myObj = "MyString"は、物事が明確になるかもしれない考え

+0

私の編集を参照してください... –

8

問題は、インターフェイスを使用してIListAddRangeを持っていませんが、あなたはそれが動作します

List<MyClass> foo = new List<MyClass>(); 

に変更した場合AddRange

を持ってListしているということです。この方法があるので。

彼らは両方以下となります。ここでは

IListあなたはまた、

IEnumerable<MyClass> foo = new List<MyClass>(); 

を行うことができますし、これはあなたのEDIT FORそれがさらに

EDITを拘束していることがわかります

を持っているものです両方ともまだListsであるため、同じタイプにしてください。違いは、使用している変数になります。インターフェイスを使用することによって、操作がインターフェイスがサポートする操作に制限されます。 ListIListを実装しているため、IListにはListのサブセットがあります。

基本オブジェクトはまだListです。

+0

私の編集を参照してください... –

+0

@Schneider更新された回答を参照してください –

0

してみてください。

List<MyClass> foo = new List<MyClass>(); // CHANGED TO List<> rather than IList<> 
var bar = new List<MyClass>(); 

foo.AddRange() // doesn't compile 
bar.AddRange() // compile 
2

fooの基になる型はListですが、コンパイラが正確性を保証するために使用する静的型はIList<T>です。 fooで呼び出したものはIList<T>タイプの一部として宣言する必要があります。

0

私はあなたの質問を理解していませんが、この状況ではC#とC++は同じように動作します。あなたの例では、コードをコンパイルするように書くことができます。

IList<MyClass> foo = new List<MyClass>(); 
var bar = new List<MyClass>(); 

((List<MyClass>)foo).AddRange(); 
bar.AddRange() // compile 

実際、C++のdynamic_castと同じ意味を持ちます。

0

上記のIListはすべてAddRangeをサポートしておらず、サポートする必要はありません。

次のことが可能です。

1) ((List<MyClass>)foo).AddRange(anotherList); 
2) You can also use extension method to AddRange 
3) There are another workarounds for this problem e.g. Concat etc. 

私はまた、インタフェースはあなたが抽象化を必要とするいくつかの点でクラス上のすべての機能をサポートしてはならないと、これはインターフェイス分離原則に基づくものでなければならないと思います。

関連する問題