Object Inheritance - Save Function - Return Type forced to BaseClassObject Inheritance - Save Function - Return Type forced to BaseClass
Old forum URL: forums.lhotka.net/forums/t/53.aspx
RanceDowner1234 posted on Tuesday, May 09, 2006
Hey all I'm a newbie to the CSLA.net framework, but so far I am finding it to be great, when creating non-inherited classes. I've created several of these non-inherited classes in an accounting application I'm writing, but now I'm getting to a more complex part of the coding where I'm trying to implement Object Inheritance.
I have an object called PhoneCompanyStatement, derived from StatementBase, derived from LineItemBase, which is finally derived from BusinessBase(Of LineItemBase). I will have other objects such as GasCompanyStatement, ElectricCompanyStatement, etc that derive from StatementBase too.
It seems to be standard OOP. My PhoneCompanyStatement has all but 4 public properties in common with a GasCompanyStatement, ElectricCompanyStatment, etc. So I created a base class called StatementBase which contains some 20 properties that "all" statments have in common.
In turn a "Statement" is just a "line item" which has fields in common with PaymentBase and PenaltyBase. So I created a LineItemBase on which StatmentBase, PaymentBase, and PenaltyBase will all derive.
But while creating the Factory Methods I tried the following line of code I get two compile errors on the Save Override:
<System.Serializable()> _
Public Class PhoneCompanyStatement
Inherits StatementBase 'Note: StatementBase inherits LineItemBase, which inherits BusinessBase(Of LineItemBase)
''' Other Code
#Region " Factory Methods "
Public Overrides Function Save() As PhoneCompanyStatement
Return MyBase.Save
End Function
#End Region
''' Other Code
End Class
I get two compile errors:
Error 1 'Public Overrides Function Save() As PhoneCompanyStatement' cannot override 'Public Overridable Function Save() As LineItemBase' because they differ by their return types.
Error 2 Option Strict On disallows implicit conversions from 'FeesDataObjects.LineItemBase' to 'FeesDataObjects.PhoneCompanyStatement'.
I can only make the compile errors go away if I change the return type of the save function to the lowest level BaseClass type.
Public Overrides Function Save() As LineItemBase
Return MyBase.Save
End Function
Is this a good idea? It just doesn't look right to me. It doesn't seem standard OOP to me. But maybe I'm wrong?
Has anybody worked with Inheritance chains like this before in CSLA.net. And if so how did you implement the Save Function.
Thanks for any help.
Rance Downer
rancedowner1234@hotmail.com
Jav replied on Tuesday, May 09, 2006
My guess is that the reason the "compiler" likes LineItemBase is because that is the final type Of generic(for lack of a better term) you have declared. In other words, I think, that you are saying that your inheritance looks like this:
Public Class LineItemBase
Inherits Csla.BusinessBase(Of LineItemBase)
Public Class StatementBase
Inherits LineItemBase
Public Class PhoneCompanyStatement
Inherits StatementBase
As far as the Return value from Save is concerned, it is okay even if it is LineItemBase - you will just need to cast it back like:
Mystatement = CType(Mystatement.Save(), PhoneCompanyStatement)
and you will only need to do that if you are going to continue to use "MyStatement" object after the Save. If you are not, it don't mean noth'n whatcha got back since y'all gonna squash it anyway.
Jav
Gigatron replied on Wednesday, May 10, 2006
I have have a similar need for my project. Jav's suggestion helped, but my generics looked like this:
Public
Class AddressBase(Of T As AddressBase(Of T))
Inherits BusinessBase(Of T)
End
Class
Public
Class CentreAddress
Inherits AddressBase(Of CentreAddress)
End
Class
Is this correct way of approaching? It compiles, but I haven't tested yet.
Jav replied on Wednesday, May 10, 2006
Gigatron
It looks like AddressBase is the final class in your inheritance. If that is the case, then I would simply do this.
Public Class AddressBase
Inherits Csla.BusinessBase(Of AddressBase)
Otherwise - if you do it your way, every place you have to express the Type of AddressBase, you will run into problems. For example, when you declare
Private MyAddress As AddressBase
the compiler would not let you do that.
Jav
Jav replied on Wednesday, May 10, 2006
Gigatron
Sorry - I did not read your entire post. Yes you are doing it right.
Javxal replied on Tuesday, May 09, 2006
Hey!
It sounds like you should be creating your base classes generic.
Like
Public Class LineItemBase(Of T as LineItemBase)
Inherits BusinessBase(Of T)
...
End Class
and
Public Class StatementBase(Of T as StatementBase)
Inherits LineItemBase(Of T)
...
End Class
Your final class will be
Public Class PhoneCompanyStatement
Inherits StatementBase(Of PhoneCompanyStatement)
...
End Class
I hope it helps!
Andrés
RanceDowner1234 replied on Wednesday, May 10, 2006
Thanks. I will try the generics route.
Most of the time I only call Save( ) as a subroutine for instance I'll say:
Call PhoneCompanyStatement.Save( )
But I just figured if other people in my company used my object it might be nice if they could count on the return value being passed back as same type as the object.
I suppose it's not too bad if they cast it back like:
Dim myReturn As LineItemBase
myReturn = PhoneCompanyStatement.Save( )
Dim newObj As PhoneCompanyStatment
newObj = CType(myReturn, PhoneCompanyStatement)
But for some reason that just didn't seem right.
But if I have a hard time with the generics... as I've used generics before, but never built them... I'll go the Cast route instead.
But for now, thanks for the advice on the generics. I'll give that a schoolhouse try!
Much thanks to both of you for your help!
Rance
RanceDowner1234 replied on Wednesday, May 10, 2006
Just wanted to let you know. The generics worked beautifully!!! Gracias, gracias mi amigo.
I was a little nervous at first, but really it wasn't that hard to build. It was just a matter of declaring the types correctly. It was almost exactly as xal's code two threads above. With one minor tweak. I will post the change in case anyone else can benefit from the experience.
Here's the Final Code... The basic addition was the "(Of T)" lines...
Public MustInherit Class LineItemBase(Of T As LineItemBase(Of T))
Inherits BusinessBase(Of T)
Public MustInherit Class StatementBase(Of T As StatementBase(Of T))
Inherits LineItemBase(Of T)
Public Class PhoneCompanyStatement
Inherits StatementBase(Of PhoneCompanyStatement)
''''Other factory methods like GetInstance(byval id as Integer)
'This line works now!!!!
Public Overrides Function Save() As PhoneCompanyStatement
Return MyBase.Save
End Function
End Class
Other code...
Dim Obj As PhoneCompanyStatement
Obj = PhoneCompanyStatement.GetInstance([id])
Dim copyObj As PhoneCompanyStatement
copyObj = Obj.Save( )
Thanks again Guys. I might be able to use this generics stuff in other places now too!
Rance
xal replied on Wednesday, May 10, 2006
Oops!
How about having the forum engine compile the code samples we post?
Or better yet, intellisense!
Sorry.
Anyway, I'm glad you found your way!
Andrés
lazaroms replied on Saturday, July 10, 2010
Hola Andrés:
¿Pudieras dejarme un correo para hacerte algunas consultas en
español?
Saludos,
Lazaro Manuel Santin.
Lmsantin@yahoo.es
Copyright (c) Marimer LLC