Design Problem: Abstract Class inheriting from a List(Of AnotherAbstactClass)

  • Thread starter Thread starter Etienne-Louis Nicolet
  • Start date Start date
E

Etienne-Louis Nicolet

I try to figure out how to solve the following problem:

- I'd like to create an abstract class which should serve as base class for
various collections (lets call it 'MyCollection').
- All these collections contain items which inherit from the an abstract
class (e.g. 'MyClass'). The constructor of MyClass requires parameters.
- In either the constructor or a method in MyCollection I'd like to put the
code to add the items to to collection - something like 'Me.Add(New
MyClass(...))'. But since abstract classes can not be instantiated, how
would I have to code it?


Public MustInherit Class MyClass(Of TDataRow As DataRow)

Protected Sub New(pDataRow As TDataRow)
....
End Sub

End Class

Now I'd like to create another abstract class which inherits from MyClass as
follows:

Public MustInherit Class MyCollection(Of TDataRow As DataRow)
Inherits List(Of MyClass(Of TDataRow))

Protected Sub New(...)
' **********
' Here's the problem: The derived class should add instances
' of classes inherited from MyClass
' It should look something like
' **********
[Loop]
Me.Add(New MyClass(Of TDataRow)(pDataRow))
[End Loop]
End Sub

End Class


Many thanks for any suggestions,
Etienne
 
Etienne-Louis Nicolet said:
I try to figure out how to solve the following problem:

- I'd like to create an abstract class which should serve as base
class for various collections (lets call it 'MyCollection').
- All these collections contain items which inherit from the an
abstract class (e.g. 'MyClass'). The constructor of MyClass requires
parameters. - In either the constructor or a method in MyCollection
I'd like to put the code to add the items to to collection -
something like 'Me.Add(New MyClass(...))'. But since abstract classes
can not be instantiated, how would I have to code it?


Public MustInherit Class MyClass(Of TDataRow As DataRow)

Protected Sub New(pDataRow As TDataRow)
....
End Sub

End Class

Now I'd like to create another abstract class which inherits from
MyClass as follows:

Public MustInherit Class MyCollection(Of TDataRow As DataRow)
Inherits List(Of MyClass(Of TDataRow))

Protected Sub New(...)
' **********
' Here's the problem: The derived class should add instances
' of classes inherited from MyClass
' It should look something like
' **********
[Loop]
Me.Add(New MyClass(Of TDataRow)(pDataRow))
[End Loop]
End Sub

End Class


If I am not mistaken, this is not possible in this way because, during
compilation, there is no guarantee that the generic type will be creatable
(constraint: new). If I see it right it does not even has anything to do
with generics because you want to create an instance of "MyClass". This
has nothing to do with the generic TDataRow type. I mean, you would have
the same problem without generics:
(I've changed the names because MyClass is a reserved word)

Public MustInherit Class ItemBase

Protected Sub New(ByVal pDataRow As DataRow)
End Sub

End Class

Public MustInherit Class MyCollection
Inherits List(Of ItemBase)

Protected Sub New()
Me.Add(New ItemBase(Nothing)) '<<<< also can not work
End Sub

End Class



If possible, you can create the instances of the classes derived from
MyClass in the collections derived from MyCollection. You can add a
MustOverride function to MyCollection that creates the items if overriden in
the derived collection. Something like this:

Public Class MyDataRow
Inherits DataRow
Sub New()
MyBase.New(Nothing) '"Nothing" just for testing
End Sub
End Class

Public MustInherit Class ItemBase(Of TDataRow As {DataRow})
Protected Sub New(ByVal pDataRow As TDataRow)
End Sub
End Class

Class ItemDerived
Inherits ItemBase(Of MyDataRow)
Sub New(ByVal row As MyDataRow)
MyBase.New(row)
End Sub
End Class

Public MustInherit Class MyCollection(Of TDataRow As {DataRow})
Inherits List(Of ItemBase(Of TDataRow))
Protected MustOverride Function CreateItem _
(ByVal row As TDataRow) As ItemBase(Of TDataRow)

Protected Sub New()
Me.Add(CreateItem(Nothing))
End Sub
End Class

Public Class MyDerivedCollection
Inherits MyCollection(Of MyDataRow)

Protected Overrides Function CreateItem _
(ByVal row As MyDataRow) As ItemBase(Of MyDataRow)
Return New ItemDerived(row)
End Function
End Class


Though, don't know if that's doable.


Armin
 
Armin said:
If I am not mistaken, this is not possible in this way because, during
compilation, there is no guarantee that the generic type will be
creatable (constraint: new). If I see it right it does not even has
anything to do with generics because you want to create an instance
of "MyClass". This has nothing to do with the generic TDataRow type. I
mean, you would
have the same problem without generics:

Addendum:
Even with a 'new' constraint, the class would have to have a parameterless
constructor. Anyway, the constraint could only be applied to the generic
type, not the abstract class itself. In other words, you don't intend to
create an instance of TDataRow but an instance of MyClass.


Armin
 
Etienne-Louis Nicolet said:
I try to figure out how to solve the following problem:

- I'd like to create an abstract class which should serve as base class for
various collections (lets call it 'MyCollection').
- All these collections contain items which inherit from the an abstract
class (e.g. 'MyClass'). The constructor of MyClass requires parameters.
- In either the constructor or a method in MyCollection I'd like to put the
code to add the items to to collection - something like 'Me.Add(New
MyClass(...))'. But since abstract classes can not be instantiated, how
would I have to code it?

Public MustInherit Class MyClass(Of TDataRow As DataRow)

Protected Sub New(pDataRow As TDataRow)
....
End Sub

End Class

Now I'd like to create another abstract class which inherits from MyClass as
follows:

Public MustInherit Class MyCollection(Of TDataRow As DataRow)
Inherits List(Of MyClass(Of TDataRow))

Protected Sub New(...)
' **********
' Here's the problem: The derived class should add instances
' of classes inherited from MyClass
' It should look something like
' **********
[Loop]
Me.Add(New MyClass(Of TDataRow)(pDataRow))
[End Loop]
End Sub

End Class
<snip>

You may have an abstract method in the collection itself:

<example>
MustInherit Class MyCollection(Of TDataRow As DataRow)
...
MustOverride _
Function NewItem(P As TDataRow) As MyClass(Of TDataRow)
...
Protected Sub New(ParamArray Items() As TDataRow)
...
For Each I As TDataRow In Items
Me.Add(NewItem(I))
Next
...
End Sub
End Class

...
'A concrete class
Class CustomerList
Inherits MyCollection(Of CustomerRow)
...
Overrides _
Function NewItem(P As CustomerRow) As MyClass(Of CustomerRow)

'In this example, CustomerFoo, CustomerBar and CustomerBaz
'are derived from MyClass(CustomerRow)

If SomeConditions Then
Return New CustomerFoo(P)
ElseIf SomeOtherConditions Then
Return New CustomerBar(P)
Else
Return New CustomerBaz(P)
End If
End Function
</example>

HTH.

Regards,

Branco.
 
Branco said:
Etienne-Louis Nicolet said:
I try to figure out how to solve the following problem:

- I'd like to create an abstract class which should serve as base class
for
various collections (lets call it 'MyCollection').
- All these collections contain items which inherit from the an abstract
class (e.g. 'MyClass'). The constructor of MyClass requires parameters.
- In either the constructor or a method in MyCollection I'd like to put
the
code to add the items to to collection - something like 'Me.Add(New
MyClass(...))'. But since abstract classes can not be instantiated, how
would I have to code it?

Public MustInherit Class MyClass(Of TDataRow As DataRow)

Protected Sub New(pDataRow As TDataRow)
....
End Sub

End Class

Now I'd like to create another abstract class which inherits from MyClass
as
follows:

Public MustInherit Class MyCollection(Of TDataRow As DataRow)
Inherits List(Of MyClass(Of TDataRow))

Protected Sub New(...)
' **********
' Here's the problem: The derived class should add instances
' of classes inherited from MyClass
' It should look something like
' **********
[Loop]
Me.Add(New MyClass(Of TDataRow)(pDataRow))
[End Loop]
End Sub

End Class
<snip>

You may have an abstract method in the collection itself:

<example>
MustInherit Class MyCollection(Of TDataRow As DataRow)
...
MustOverride _
Function NewItem(P As TDataRow) As MyClass(Of TDataRow)
...
Protected Sub New(ParamArray Items() As TDataRow)
...
For Each I As TDataRow In Items
Me.Add(NewItem(I))
Next
...
End Sub
End Class

...
'A concrete class
Class CustomerList
Inherits MyCollection(Of CustomerRow)
...
Overrides _
Function NewItem(P As CustomerRow) As MyClass(Of CustomerRow)

'In this example, CustomerFoo, CustomerBar and CustomerBaz
'are derived from MyClass(CustomerRow)

If SomeConditions Then
Return New CustomerFoo(P)
ElseIf SomeOtherConditions Then
Return New CustomerBar(P)
Else
Return New CustomerBaz(P)
End If
End Function
</example>

HTH.

Regards,

Branco.

Armin, Branco,

Thank you very much for your support! It appears to me that Branco's appoach
does the trick to me.

Kind regards,
Etienne
 
Back
Top