By Greg McGuffey - 8/21/2008
I have a base form that has a BusinessLayer property. I then call the FillByPrimaryKey method on this BusinessLayer property (which is of course set to some concrete BO).
I have a BO were I've overloaded the FillByPrimaryKey method (marked method in BO with "Overloads"). I thought that this would hide the FillByPrimaryKey method in BusinessLayer, but apparently it doesn't..my overload never gets called from the form, the one in BusinessLayer gets called. I must not be understanding how this should works...
How do I overload FillByPrimaryKey (or FillByParent, etc) so I can use a generic BusinessLayer (program to the abstract class/base class), but use the overload in a specific BO if needed?
|
By Dustin Taylor - 8/22/2008
First off, are you using your own subclassed business layer BO as the business layer on your base form? If not, then it won't see your changes.Second, do you mean overrides rather than overload? And if so, are you marking the method as overrides? An overload means you are creating another definition for the FillByPrimaryKey with a different argument list. If you are doing that, and use your own, different, argument list then it should be finding your overloaded call. If you are calling FillByPrimaryKey with only the primary key passed (the same argument list), then you will need to override that method, so that it uses your definition rather than ours.
|
By Greg McGuffey - 8/22/2008
First off, are you using your own subclassed business layer BO as the business layer on your base form? If not, then it won't see your changes.
My BO is a couple of base classes removed from BusinessLayer.
Second, do you mean overrides rather than overload?
No, I mean Overloads. I can't override it because FillByPrimaryKey isn't marked Overridable. The only choice I have is to overload (shadow kind of overload). The signature isn't different though. I'm overloading FillByPrimaryKey(primaryKey As Integer). Here's an example of what's going on:
' Create an instance of my BO, with the Overloads of FillByPrimaryKey
Dim myBO As New FillByPrimaryKeyOverLoadBO()
' Fill BO via pk...this does use my overload of FillByPrimaryKey
myBO.FillByPrimaryKey(id)
' Assign this bo to a variable that is a BusinessLayer
Dim genericBO As BusinessLayer
genericBO = myBO
' Now fill by primary key again, this time uses the BusinessLayer FillByPrimaryKey
genericBO.FillByPrimaryKey(id)
If you are calling FillByPrimaryKey with only the primary key passed (the same argument list), then you will need to override that method, so that it uses your definition rather than ours.
As mentioned, I can't. I tried, but the compiler no likely . FillByPrimaryKey isn't overridable.
During the course of posting this, I built a quick demo and it is now pretty obvious to me what the rules are. When overloading a base class method with the same signature, if you access that method from your object typed as itself, you get the overloaded method. If you cast to the base type, you get the base method. If you inherit from a type that overloads a method from its parent type (A inherits from B inherits from C, B overloads a method in C), you get the overloaded method in the parent (A.method -> overloaded method in B). This is a good think, as you can still get to the original methods via casting.
However, I believe it means that the answer to my question of how to override FillByPrimaryKey is that you can't. The only way to get to the overload would be to access the method from the derived type or a type that inherits from that type....unless FillByPrimaryKey is marked Overridable.
I have a demo solution (VS 2008) for anyone who's interested.
Thanks for getting me thinking Dustin!
|
By Trent L. Taylor - 8/22/2008
OK, here is the deal. If you are programming in VB.NET, which I think that you are, then you will either need to override (which as you mentioned these are not presently marked as overridable) or Shadow the method. You will need to explicity assign the Shadows to you method or the BusinessLayer logic will be what gets called.Public Shadows Sub FillByPrimaryKey(ByVal pk As Integer) '-- Place your logic here End Sub I just verified that what I am telling you is correct and it should work just fine. Now it really wouldn't be a bad idea to allow these to be overridable anyway...so I will add this to the list. If you can't get this worked out then let me know and I will make these overridable and post an update sooner rather than later.
|
By Greg McGuffey - 8/22/2008
Thanks for your replies. Yep, I use VB.NET. I just did some testing using the Shadows keyword (instead of Overloads) and the results are the same. To reiterate what I was trying to do:
- I have a base form that has a BusinessObject property (I probably should have used the PrimaryBusinessObject, but I wasn't that smart and added my own ). It is of type BusinessLayer.
- This form also has an IdToLoad property (integer...I'm using integer PK always) that indicates the ID of a record to load.
- In OnLoad of this base form, I check if IdToLoad is > 0 and if it is, load that ID automatically via Me.BusinessObject.FillByPrimaryKey(Me.IdToLoad)
- For one of my BOs, I'm overloading the FillByPrimaryKey to add a couple of other columns. I used the Overloads keyword, but based on testing, the Shadows keyword would work the same. When I try to auto load by setting the IdToLoad, the call to Me.BusinessObject.FillByPrimaryKey(Me.IdToLoad) (and Me.BusinessObject is set to this BO with the overloaded FillByPrimaryKey) actually calls the FillByPrimaryKey method in BusinessLayer, NOT my overload. After getting my head wrapped around it, based on my testing, this is expected.
I've already fixed this, so in the case of the form using this BO, it skips the auto loading and instead uses the overloaded FillByPrimaryKey. So no rush on marking the FillByXxx methods with Overridable, though that will be a welcome enhancement.
A couple of last comments (for the lurkers ).
- The difference between Shadows and Overloads is that Shadows overloads all signatures for a method, were as Overloads only overloads the matching signature.
- While it was annoying that this didn't work, now that I understand it, it makes sense. Overloading in this fashion (as opposed to overloading a method's signature) hides base class functionality. The way this is implemented allows for both the new functionality and the base class functionality to be available, based on the type.
I'm including a solution that demonstrates all of this. It uses the StrataFrameSamples db. Thanks for the, as usually, outstanding help and for the future enhancement to mark these methods overridable.
|
By Peter Denton - 8/24/2008
Greg,I haven't tested my theory, but I suspect that the reason the shadows is not having the effect you want is because the BO in which you have applied it is being accessed not as the "GregSpecialBO" Type that it is but as "BusinessLayer". Therefore where it is being used it doesn't know about all the "GregSpecial" things, only the standard "BusinessLayer" things, which means the standard "FillByPrimaryKey", rather than the special one you've shadowed it with is being used. Having said that, accessing the BO as a "GregSpecialBO" my introduce all kinds of other complications. And more to the point I could be completely wrong! Peter
|
By Greg McGuffey - 8/25/2008
Peter,
Thanks for the response. Your theory is correct. The sample I posted clearly shows this. I was confused about how shadowing (overloading a method with the same signature from a base class) differed from overriding (overriding a method that is marked Overridable in the base class) in VB.NET (I'm not confused about how C# works...just clueless ).
In the case of shadowing, it is as you say. If I access GregSpecialBO, then my overloaded method is available. If I cast GregSpecialBO to BusinessLayer, then I get the base method. This makes sense because it has to handle the situation were I've created a method in my subclass, then, later, the base class adds a method of the same name with the same signature. How would I get to the base class method? The way it is handled allows casting to control which method I use.
On the other hand, overriding an Overridable method actually replaces the method. This means that calling the overriden method in either GregSpecialBO or on GregSpecialBO cast to BusinessLayer always calls the overriden method.
Most of you probably already know this...I guess I'm mostly typing this so I won't ever forget this again!
|
|