2017-07-27 11 views
41

の一覧を表示する一覧 から変換できません。タイプのオブジェクトリスト は、私はこのように設定している<Foo>

List<Bar> barList = new List<Bar>() 
AddEntries(barList); 

しかし、これは私にエラー:

cannot convert from List<Bar> to List<Foo>

この問題は解決しましたか?私は、抽象クラスを使用してメソッド定義を保持する必要があります。あなたのAddEntriesがジェネリックにすると、この

void AddEntries<T>(List<T> test) where T : Foo 
{ 
    //your logic 
} 

にそれを変更することができ

+1

は、C#は、<リスト 'のような構文を持っていますか? JavaのようにFoo>を拡張しますか? – dbush

+2

@dbushはい、C#のバージョンは受け入れられた答えです – Harrichael

+4

@harrichael Javaとは異なり、C#は一般的な共分散をサポートしていますので、さらに良いオプションがあります。(Robの答えを参照してください) –

答えて

60

Covariance and Contravariance in Generics from docs.microsoft.comこれを読んでください。特に、「共変タイプのパラメータを持つ汎用インターフェース」は、使用しているシナリオをカバーします。要するに

、あなたがあなたのAddEntriesメソッドのシグネチャを変更する(できる)場合:

static void AddEntries(IEnumerable<Foo> entries) 

IEnumerable<Foo>代わりのList<Foo>の使用に注意してください)あなたが探しているものを行うことができるでしょうする。

ここでの具体的な違いはIEnumerable<T>List<T>が異なって宣言されていることである。

public interface IEnumerable<out T> : IEnumerable 
public class List<T> : IList<T>, ... ... 

を重要という違いは、それは(意味共変であることを示しているIEnumerable<T>の宣言でoutです定義はdocs.microsoft.comから取得):

Covariance: Enables you to use a more derived type than originally specified.

+1

メソッド名がAddEntriesであることを考慮すると、OPがIEnumerableを使用することはほとんどありません。 – Taemyr

+0

@Taemyrしかし、OPは 'interface'を定義することができます。 – wizzwizz4

+7

@Taemyr: 'AddEntries'は「このリストにいくつかのエントリを追加する」ではなく、「これらのエントリを他のリストに追加する」という意味です。そうでなければ、 'FooChild'を' List 'に無関係に追加することはできないので、どちらの答えも彼のためには機能しません。 –

43

これは単純な理由で許可されていません。以下のコンパイルと仮定:

AddEntries(new List<Bar>()); 

void AddEntries(List<Foo> list) 
{ 
    // list is a `List<Bar>` at run-time 
    list.Add(new SomethingElseDerivingFromFoo()); // what ?! 
} 

をあなたのコードはコンパイルしたい場合、あなたが実際にList<Bar>(ランタイム型)SomethingElseDerivingFromFooを追加しました(全体の一般的なリストが無意味になる)危険な追加を持っています。あなたの問題を解決するために

、あなたはジェネリックを使用することができます。

void AddEntries<T>(List<T> list) where T:Foo 
{ 

} 
+3

理由を説明するために上手くいっていますか?*なぜあなたはキャストをすることはできません。 –

+0

私は分かりません。これは完全に有効なコードです(http://ideone.com/xoNJX8)。派生クラスで提供されている追加の機能(明示的なキャストなし)に依存することはできません。 – Phylogenesis

+1

@Phylogenesis 'List 'を 'AddEntries'に渡すことはできません。そのリストに' SomethingElseDerivingFromFoo'を追加した場合、それは奇妙な動作になります( 'List 'に 'SomethingElseDerivingFromFoo'項目があります。コードを完全にコンパイルして投稿しました。 – user3185569

関連する問題