views:

49

answers:

2

Time for a theoretical question I just ran across.

The following code is valid and compiles:

public class Parent
{
    public virtual object TestProperty { get; set; }
}

public class Child : Parent
{
    private string _testValue = "Hello World!";

    public override object TestProperty
    {
        get { return _testValue; }
    }
}

public class Consumer
{
    Parent p = new Child();

    public Consumer(){ p.TestProperty = 3; }
}

My question is:

Why does C# allow me to partially override the TestProperty auto property in a child when it leads to partially unpredictable behavior? Is there a practical application?

I'm allowed to set the value of TestProperty using the parent's setter (I checked the IL being generated and the setter is still setting the backing object in the parent class) even though value is not accessible to the public.

+4  A: 

This behavior is consistent with non-auto-implemented properties in C#. It's always been possible to override only a get or set method for a virtual property. Hence making it impossible to do with an auto-implemented property would create an unnecessary inconsistency.

For example, the following is legal

class A
{
    public virtual int P1
    {
        get { return 42; }
        set { }
    }
}

class B : A
{
    public override int P1
    {
        get { return 18; }
    }
}
JaredPar
Fair enough. The question, then, isn't limited to auto-properties. Still a bit fuzzy though on the practical application. If I'm declaring my entire property as a single unit and that unit is made up of a get and set...why would I want to override one and leave the other with potentially confusing behavior?
Justin Niessner
@Justin, The get and set portions of a property are fundamentally different methods so it makes sense that they can be overriden independently. In terms of why you would want to perhaps I want to add extra validation in the setter or caching behavior in the getter but keep the default behavior for the other. I'm sure there are a number of valid use cases for doing this
JaredPar
@JaredPar - I understand that they are fundamentally different methods, but logically the two are coupled in my mind. In terms of language design, though, why not require overriding both and then if you want to keep the existing functionality you simply call return base.TestProperty();? (maybe this is why I'm not cut out for designing languages)
Justin Niessner
@Justin I think where you're stumbling is assuming that they are logically connected. Indeed this is the case the vast majority of the time. But they do not have to be and even in the case where the original 2 are it's possible to correctly override one but not the other (think caching in a derived type get override). Forcing the user to override both when one doesn't actually override is ... well wrong :)
JaredPar
@JaredPar - And there it is. Ever ask a question and then realize after somebody gives you the answer that you knew it all along but were blocking it out because you were stuck on the "Wha!?" portion? Thanks!
Justin Niessner
@Justin, had that happen plenty of times ;)
JaredPar
A: 

Doesn't it make sense for a setter, though? If you partially override only the setter, that could be useful so that you can respond to that event, in addition to calling base.TestProperty = value, without having to bother with a boilerplate override of the getter as well.

Kirk Woll