Try this on your own & you can see why even in a VERY simple case shadowing is bad and leads to VERY hard to find bugs
CustomSubclass1 and CustomSubClass2 are both subclasses of baseclass. Thatās all the set up this requires.
The code, as you can see, is VERY simple.
When you hit the breaks peek at the values in the debugger & variable pane - and scratch your head
I just did a test and it looks like you can get around this if your shadowed property is a Computed Property and sets the base class directly.
Using your example:
Set
BaseClass( me ).SomeProperty = value
Get
return BaseClass( me ).SomeProperty
Any reason not to do it that way?
Itās slightly less fragile but properties, computed or not, are still based on the static type so your computed property will still be ignored by anything using the base class.
Iām not sure what you mean. Using Normanās example code, where c was set to BaseClass, the value was set properly. I used this code:
dim c as BaseClass
c = new Sub1
c.P = 1
AddToResult Str( c.P )
c = new Sub2
c.P = 2
AddToResult Str( c.P )
Output was 1 and 2, as expected.
Where might it not work?
OH, I see what you mean, itās not going through the computed property. Bad.
Hence Kem you see why shadowing causes weird and often VERY hard to find bugs.
YOU expected it to go through the computed property and if your classes relied on that youād be tracking down a VERY hard to find ābugā
You see why we constantly tell people āDonāt do thisā
I wish Xojo officially supported property overriding via computed properties. If there is a clsParent.Visible property we should be able to created a computed property in clsChild and access Super.Visible. clsChild would not have the normal mVisible property in this case. If clsParent already has a computed property, then Super.Visible would call it.
Maybe it would be called something else in the IDE, āOverride Propertyā. With this feature the IDE could block you from creating a shadowed property. If you type an existing property name, just explain the situation and offer to create an override property in a dialog.
On numerous occasions Iāve struggled to work around the fact that we canāt do this, typically when sub classing the framework or 3rd party code. But sometimes in my own code Iāll go back, take code from computed properties, and put it in real methods so that subclasses can properly override it. Or mark a property protected then provide real method accessors so that the child classes can override.
[quote=76445:@Norman Palardy]Hence Kem you see why shadowing causes weird and often VERY hard to find bugs.
YOU expected it to go through the computed property and if your classes relied on that youād be tracking down a VERY hard to find ābugā
You see why we constantly tell people āDonāt do thisā
[/quote]
Right, I see that now. This is different behavior than if a subclass overrides a method. In those cases, it always goes through the subclass no matter how the variable is defined, so you might expect a shadowed property to do the same. As demonstrated and explained, it doesnāt.
I guess I could ask, āwhy allow it at all then?ā But I wonāt.
Because people do it and making it an error would break too much code.
See? Thatās why I didnāt ask.
[quote=76447:@Daniel Taylor]I wish Xojo officially supported property overriding via computed properties. If there is a clsParent.Visible property we should be able to created a computed property in clsChild and access Super.Visible. clsChild would not have the normal mVisible property in this case. If clsParent already has a computed property, then Super.Visible would call it.
[/quote]
Get / Set pairs are such a thing - they are virtual.
Properties, computed or not, are NOT virtual.
Make the property private & implement a pair of methods & youāre off to the races.
Consumers of your classes are not aware of any such changes which is really nice as you can move from a public property to computed to get/set pair with no changes required in users of your code.
Few other languages allow you to do this quite as invisibly.
The main beef I have with making computed properties be virtual is that now the framework has to document which properties are computed versus non-computed and it becomes an API contract.
What about ContainerControls?
I add computed properties to a ContainerControl that get/set the properties that I want to modify in the ContainerControl.
Is this ok or is this evil too?
I would like to see the ability to declare an override property regardless of whether or not the parent class has a computed property or just a plain old property, i.e. I basically wish properties were virtual. So there wouldnāt be a need to document computed/non-computed in the framework because Super.Property would access whatever the parent class has. In a sense public properties are already part of an API contract. We just canāt add to their behavior in a subclass.
I realize Iām describing this without any knowledge as to how much work it would require in the Xojo runtime and compiler, and that it may never exist. Iām just pointing out that this is an issue I do run into in Xojo.
Thatās the issue. You canāt do that with code you do not control. In that case you have to create Get/Set methods and change code all over the place to use them. But even that can be a problem when thereās additional code you do not control which accesses the property directly.
Itās not an every day thing, but when you run into itā¦
Iām wincing at the performance impact this would have in terms of up front cost and the cost of missing optimization opportunitiesā¦
Would it matter on a modern CPU? I just wrote a quick million loop test and clocked property access at roughly 35,000 microseconds for the entire loop, and method access to the same property at roughly 58,000 microseconds. 23k microseconds divided by a millionā¦thereās no real difference there.
I realize that doesnāt take into account optimization opportunities. But Iāve never perceived a performance difference after renaming/protecting a property and creating accessor methods under the old name.
Even though programs have a ton more resources to eat, performance still matters. I know there are people in the community who are writing physics simulation and they need all the speed they can get. Thatās not to say that performance should be the compilerās only concern, but it is up there when considering language changes this large.
This is under the current compiler, which doesnāt attempt any optimizations. The new compiler will be an optimizing compiler that will be able to do all sorts of clever things.
[quote=76455:@Markus Winter]What about ContainerControls?
I add computed properties to a ContainerControl that get/set the properties that I want to modify in the ContainerControl.
Is this ok or is this evil too?[/quote]
Same problem as noted above
It relies on the static type of the declared variable and not the runtime type
So if you have a container thats a parent for others be VERY careful as you will have the same problems
I use a different name for my new property instead of trying to shadow one & cause myself untold hours of grief
The other thing that making properties virtual may do is introduce new unexpected side effects in existing code - it would just quietly change behavior and thats a bigger problem potentially
Honestly, you would have to convince me with a test case that showed a difference of at least a few seconds, and that would be difficult even in a physics sim. Virtual vs. non-virtual hasnāt been a performance issue in any language sinceā¦the 1990ās?
LLVM might miss some optimization opportunities with virtual properties, but itās going to so radically improve performance to begin with that youāll still be in the black (if XojoScript is any indication).
Again, while I would like virtual properties, Iām not expecting this feature. Just thinking out loud.
Compiler option
Iām half joking because one of the nice things about Xojo is that you donāt have to double check 50 compiler options to make sure your code runs correctly (Iām looking at you C/C++/obj.C).