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.List
1[NtnAgent.LicenseFileDataNode]' can't be converted to an object of the type 'System.Collections.Generic.IList
1[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!
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 EvilAnimal
s into your List<Animal>
, and that is clearly absurd because an EvilAnimal
is not an Animal
.
> "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
精彩评论