UFCS & overloaded property getters/setters

H. S. Teoh via Digitalmars-d digitalmars-d at puremagic.com
Fri Jun 13 11:16:45 PDT 2014


On Fri, Jun 13, 2014 at 10:53:38AM -0700, Jonathan M Davis via Digitalmars-d wrote:
> On Fri, 13 Jun 2014 09:39:04 -0700
> "H. S. Teoh via Digitalmars-d" <digitalmars-d at puremagic.com> wrote:
> 
> > I'm not sure if this is a bug, or an anti-pattern, or what, but I ran
> > into this issue yesterday:
> >
> >   class Base {
> >       int propImpl;
> >       final @property int prop() { return propImpl; }
> >       @property void prop(int newVal) { propImpl = newVal; }
> >
> >       void someMethod() {
> >           auto x = prop; // OK, calls Base.prop()
> >           prop = x; // OK, calls Base.prop(int)
> >       }
> >   }
> >
> >   class Derived : Base {
> >       override @property void prop(int newVal) {
> >           super.prop(newVal);
> >           doSomethingElse(newVal);
> >       }
> >
> >       void someOtherMethod() {
> >           auto x = prop; // NG - compile error ***
> >           auto y = super.prop; // OK, calls Base.prop()
> >           prop = x; // OK, calls Derived.prop()
> >       }
> >   }
> >
> > Basically, once the derived class overrides the property setter, the
> > (un-overridden) base class getter somehow becomes shadowed as well,
> > and references to .prop will cause a compile error saying that
> > Derived.prop can't be called without parameters.
> >
> > So, what's going on here? Should this code be accepted? Is this a
> > compiler / language bug? A deliberate @property limitation? Or just
> > more evidence @property should be taken out the back and shot?
> 
> This is normal and has nothing to do with @property. When you override
> a function in a derived class, you either have to override all its
> overloads in the derived class or alias the base class symbols in the
> derived class, or all the base class overloads which weren't
> overridden are hidden. I believe that it's one of D's attempts to
> avoid function hijacking. And I believe that it is discussed in the
> language docs somewhere.
[...]

Aliasing super.prop to .prop in the derived class didn't work, in fact,
it made things worse; now I have an infinite loop because all
occurrences of .prop get redirected back to the base class (including
the setter), and there is no way to alias only the non-overridden getter
overload, so a call to Derived.prop will end up in the base class method
where it shouldn't.

I think this is starting to show itself as an anti-pattern, or at least,
one of those obscure dark corners of D infested with complex
interactions between unexpected features and possible compiler quirks.
Probably the best thing to do is to make both getter and setter final,
and add an overloadable onPropSet() method that the derived class can
use to customize the property.


T

-- 
Why do conspiracy theories always come from the same people??


More information about the Digitalmars-d mailing list