2011-02-07 12 views
0

プロパティをインターフェイスのインターフェイスコレクションとして宣言し、後でその明示的な型をコンストラクタにインスタンス化したいとします。このようなもの。もちろんプロパティとインターフェイス

Public Class LicenseFile 
    Implements ILicenseFile 

    Public Property Collection As IList(Of ILicenseFileDataNode) 

    Public Sub New() 
     Collection = New List(Of LicenseFileDataNode) 'here throws an exception. 
    End Sub 

End Class 

、LicenseFileDataNodeを実装ILicenseFileDataNode

コンストラクタのユニークなラインのようなものと言って例外起動します。

「タイプ 「System.Collections.Genericのオブジェクトを。リスト1[NtnAgent.LicenseFileDataNode]' can't be converted to an object of the type 'System.Collections.Generic.IList 1 [NtnAgent.ILicenseFileDataNode] '。

つまり、t彼は「なぜそれがうまくいかなかったのか」という質問をしています。これは単純化されたシナリオですが、ワークラウンドを取るのは簡単ですが、失敗するため理由を理解する必要があります。

ありがとうございます!

答えて

1

理由を簡単にしましょう。例えば、IAnimalがあなたのインターフェイスで、AnimalIAnimalを実装する具体的なタイプであるとします。まあ、List<Animal>IList<IAnimal>ではありません。どうして? List<Animal>Animalのインスタンスを受け入れることができ、IList<IAnimal>IAnimalを実装するオブジェクトを受け入れることができるからです。考えてみましょう:

class Animal : IAnimal { } 
class EvilAnimal : IAnimal { } 

だから我々はタイプIList<IAnimal>の変数にList<Animal>のインスタンスを割り当てることができれば、あなたはList<Animal>EvilAnimal秒を挿入することができ、そしてEvilAnimalAnimalではありませんので、それは明らかに不合理です。

+0

+1を参照してください。さらなる研究のために、Googleの共分散とContravariance。 – StriplingWarrior

+0

リストはリストではなくリストで、このリストにEvilAnimalを追加できます。 –

+0

@Saeed: 'List 'は同じ理由で 'List 'ではありません。 'EvilAnimal'を' List 'に追加できますが、' List 'には追加できません。 'T - > List 'のマッピングは 'T'で共変しません。 – jason

1
> "Why It Didn't work"? 

IList(Of ILicenseFileDataNode) の要素型は、List(Of LicenseFileDataNode)

例のELEMENTTYPEからdiffenrentあるため:LicenseFileDataNodeLicenseFileDataNodeMock両方ILicenseFileDataNode

を実装するには、両方がIList(Of ILicenseFileDataNode)に添加することができるが、List(Of LicenseFileDataNode)が を含むことができない場合LicenseFileDataNodeMockアイテム

List(Of ILicenseFileDataNode)を使用すると、正常に動作するはずです。

詳細はCovariance and Contravariance in Generics