views:

123

answers:

2

Hi, I have implemented inheritance for two parent classes called Table and Field. Each parent class has several child classes. In the Table parent class, I created a method that expects parameter List(Of Field).

I get an error when trying to pass in parameter List(Of ChildField) to the method that expects a parameter of List(Of Field). The error message is as below:

Value of type 'System.Collections.Generic.List(Of com.hlb.icisbatch.data.ChildField)'
cannot be converted to 'System.Collections.Generic.List(Of com.hlb.icisbatch.data.Field)'

My question, is it possible to pass in list of child class as parameter? If it is not a list then it works fine. But somehow it is not possible with lists?

Below is sample class structure:

    Table              Field
      |                  |
  ChildTable         ChildField

I have a method in the parent class:

Public Class Table

    Public Sub New()
    End Sub

    Public Overridable Sub setFields(ByVal list As List(Of Field)
       'Do work here'
    End Sub

 End Class

and method in child class:

Public Class ChildTable

    Public Sub New(ByVal list As List(Of ChildField)
       setFields(ChildField)
    End Sub

 End Class
+1  A: 

No, this isn't possible - and for good reason. Consider what would happen if the calling code tried to add an instance of Field (or some other derived class) to the list. Bad stuff would happen.

In .NET 4 (and presumably VB10) this is possible via covariance and contravariance of generic delegates and interfaces (not classes) - but only where it's safe. So IList(Of T) is not variant (because values go "in" and "out" of the API); IEnumerable(Of T) is covariant (so there's a conversion from IEnumerable(Of String) to IEnumerable(Of Object)) and IComparer(Of T) is contravariant (so there's a conversion from IComparer(Of Object) to IComparer(Of String) for example).

(This ability has actually been in the CLR since v2.0, but it's only surfaced in the languages and framework for .NET 4.)

Jon Skeet