I have a parent class that is also a factory. For example:
Public Class Factory
Public Function clone() as Factory
' Some logic here
' return something
End Function
Public Function all() as List (Of Factory)
' Some logic here
' return something
End Function
End Class
And then an inherited one
Public Class BookFactory
inherits Factory
End Class
I can use inflection in the Factory class to generate the proper extended objects when called by the inherited one. myBookFactory.clone() will then return a BookFactory instance and not only a Factory instance.
The problem: this BookFactory instance will be cast as Factory, since the type of the function is Factory and not BookFactory.
I’d like to do something like
Public Class Factory
Public Function clone() as Me.GetType()
' Some logic here
' return something
End Function
Public Function all() as List (Of Me.GetType())
' Some logic here
' return something
End Function
End Class
So the returned value would be correctly cast and avoid having to do this each time:
Dim myBookFactory2 = DirectCast(myBookFactory1.clone(), myBookFactory1.getType())
How can I do this?
This seems to be a variation on asking for covariant return types. As you have noticed, this is not supported by VB.NET (or C# for that matter). Typically this is asked in the context of overriding virtual methods, where it is still not allowed. There are several alternatives, each with their own pros and cons.
Use a generic template argument to specify the derived class
This is similar to the way
IComparable<T>is most commonly implemented.Additionally, if you can add a
Newconstraint to the Factory (eg:Factory(Of T {New, Factory(Of T)})) base class, you may be able to avoid using reflection.However, this does not prevent the accidental (or potentially malicious) mistake of declaring a class like this:
Also, this approach makes it impossible to create a list of factories of different types without resorting to another base class below
Factory(Of T)or declaring the list as being of object.Make new methods on the derived classes that return the specific type you want.
This allows you to hide the cast for those times when you know you have a
BookFactoryand want to get anotherBookFactory. It also lets you treat all factory types polymorphically in the normal inheritance sense. However, if you have an object typed asFactory, you will still get back an object type asFactory.Reconsider the inheritance relationship
Depending on how these classes are used, it may not make sense to use the inheritance relationship here. If you are only concerned with not retyping code, you may want to look into code generation instead.