Much browsing and gnashing of teeth hasn't got me a solution so I thought I'd come here and both get some sensible answers and general good natured derision for good measure.
Anyway, I am trying to produce a base class for an object which must be initialised. I want to inherit it and a factory method to get instances. For good measure it's VS2005 and .NET 2.0
[It's all to do with some standards that are nominally required to be adhered to and visibility outside the class or containing classes (i.e. in the rest of the application - or that portion of it in the current assembly. It's a bit challenging given things can see the private methods of their outer nested classes but not vice versa other classes (within the outer class) can't see them and may need to. Ok if the classes are private but as soon as they become public one can't scope them to restrict the bits that aren't supposed to be, so wrappers have to be produced etc. /rant over]
Anyway I want to write:-
Module Module1
Sub Main()
Dim summat As x = x.GetNew("aaaaa")
Dim summat1 As y = y.GetNew("bbbbb")
End Sub
End Module
And I have x and y:-
Class x : Inherits BaseInitialisedObject(Of x, String)
Dim x As String = "WWWW"
End Class
Class y : Inherits BaseInitialisedObject(Of y, String)
Dim x As String = "xxxxxWWWW"
End Class
And their base class:-
MustInherit Class BaseInitialisedObject(Of T As {BaseInitialisedObject(Of T, TInitParams), New}, TInitParams)
Shared Function GetNew(ByVal params As TInitParams) As T
Dim newObj As New T
If Not newObj._Init(params) Then
'Throw New InvalidOperationException("Initialisation Failed")
End If
Return newObj
End Function
Protected Sub New()
End Sub
Private Function _Init(ByVal params As TInitParams) As Boolean
End Function
End Class
Now, the above does what I expect it to but:-
- I don't understand why I need to constrain the type parameter on the class. I mean it must be one of those since it is being inherited (to be fair it just look damn ugly, but I wonder about efficiency).
- I can remove the constrain, but then the shared method will have to have the constraint added and this cannot be inferred in the consumer code. i.e. I have to explicity specify it in the call to GetNew
- Of course if I could invoke a parametered constructor I could take a different approach and only ever serve up valid ones (I might be able to do this with activator]. The shared method does do this, to a point. But all somebody has to do is add a public constructor and the can get as many invalid object as they like. [I could work around this by adding private state to the class definition, but I would have to lock to make it thread safe during construction and throw in the protected constructor when detecting this]
- Further I would prefer to find a different way of specifying the parameters for the init method so I don't have to define the type in the class definition.
Essentially I am just trying to protect from misuse by the consumers.
Anyway, I am trying to produce a base class for an object which must be initialised. I want to inherit it and a factory method to get instances. For good measure it's VS2005 and .NET 2.0
[It's all to do with some standards that are nominally required to be adhered to and visibility outside the class or containing classes (i.e. in the rest of the application - or that portion of it in the current assembly. It's a bit challenging given things can see the private methods of their outer nested classes but not vice versa other classes (within the outer class) can't see them and may need to. Ok if the classes are private but as soon as they become public one can't scope them to restrict the bits that aren't supposed to be, so wrappers have to be produced etc. /rant over]
Anyway I want to write:-
Module Module1
Sub Main()
Dim summat As x = x.GetNew("aaaaa")
Dim summat1 As y = y.GetNew("bbbbb")
End Sub
End Module
And I have x and y:-
Class x : Inherits BaseInitialisedObject(Of x, String)
Dim x As String = "WWWW"
End Class
Class y : Inherits BaseInitialisedObject(Of y, String)
Dim x As String = "xxxxxWWWW"
End Class
And their base class:-
MustInherit Class BaseInitialisedObject(Of T As {BaseInitialisedObject(Of T, TInitParams), New}, TInitParams)
Shared Function GetNew(ByVal params As TInitParams) As T
Dim newObj As New T
If Not newObj._Init(params) Then
'Throw New InvalidOperationException("Initialisation Failed")
End If
Return newObj
End Function
Protected Sub New()
End Sub
Private Function _Init(ByVal params As TInitParams) As Boolean
End Function
End Class
Now, the above does what I expect it to but:-
- I don't understand why I need to constrain the type parameter on the class. I mean it must be one of those since it is being inherited (to be fair it just look damn ugly, but I wonder about efficiency).
- I can remove the constrain, but then the shared method will have to have the constraint added and this cannot be inferred in the consumer code. i.e. I have to explicity specify it in the call to GetNew
- Of course if I could invoke a parametered constructor I could take a different approach and only ever serve up valid ones (I might be able to do this with activator]. The shared method does do this, to a point. But all somebody has to do is add a public constructor and the can get as many invalid object as they like. [I could work around this by adding private state to the class definition, but I would have to lock to make it thread safe during construction and throw in the protected constructor when detecting this]
- Further I would prefer to find a different way of specifying the parameters for the init method so I don't have to define the type in the class definition.
Essentially I am just trying to protect from misuse by the consumers.
Comment