Jonathan
Jonathan

Reputation: 12015

Properties and Interfaces

I want to declare a property as an interface collection of an interface, and I want to instanciate the explicit type later, in the constructor. Something like this.

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

Of course, LicenseFileDataNode Implements ILicenseFileDataNode

The unique line of the constructor launch an exception saying something like:

"An object of the type 'System.Collections.Generic.List1[NtnAgent.LicenseFileDataNode]' can't be converted to an object of the type 'System.Collections.Generic.IList1[NtnAgent.ILicenseFileDataNode]'.

In short, the question is "Why It Didn't work"? This is a simplified scenario, but It's easy to take a workarround, But I need understand the reason because It's fails.

Thanks!

Upvotes: 0

Views: 106

Answers (2)

jason
jason

Reputation: 241711

Let's make it simpler to reason about. Let's say IAnimal is your interface, and Animal is your concrete type that implements IAnimal. Well, a List<Animal> is not a IList<IAnimal>. Why? Because a List<Animal> can accept instances of Animal, and a IList<IAnimal> can accept objects that implement IAnimal. Consider:

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

So if we could assign an instance of List<Animal> to a variable of type IList<IAnimal>, you could insert EvilAnimals into your List<Animal>, and that is clearly absurd because an EvilAnimal is not an Animal.

Upvotes: 1

k3b
k3b

Reputation: 14755

> "Why It Didn't work"?

because the element type of IList(Of ILicenseFileDataNode) is diffenrent from the elementtype of List(Of LicenseFileDataNode)

example: if LicenseFileDataNode and LicenseFileDataNodeMock both implement ILicenseFileDataNode

then both can be added to IList(Of ILicenseFileDataNode) but List(Of LicenseFileDataNode) cannot contain LicenseFileDataNodeMock items.

Using List(Of ILicenseFileDataNode) should work as expected.

for more details see Covariance and Contravariance in Generics

Upvotes: 1

Related Questions