views:

214

answers:

4

Is it possible to do something like this?

class A
{
    public virtual string prop
    {
        get
        {
            return "A";
        }
    }
}
class B: A
{
    private string X;
    public override string prop
    {
        get
        {
            return X;
        }
        set
        {
            X = value;
        }
    }
}

That is, the base class provides a virtual property with only a GET accessor, but the child class overrides the GET and also provides a SET.

The current example doesn't compile, but perhaps I'm missing something here.

Added: To clarify, no I don't want to redefine with new. I want to add a new accessor. I know it wasn't in the base class, so it cannot be overriden. OK, let me try to explain how it would look without the syntactic sugar:

class A
{
    public virtual string get_prop()
    {
            return "A";
    }
}
class B: A
{
    private string X;
    public override string get_prop()
    {
        return X;
    }
    public virtual string set_prop()
    {
        X = value;
    }
}
+1  A: 

No, there is no way to do this. Think about how the syntactic sugar of your virtual property is being dealt with, i.e. it gets converted to:

public virtual string get_prop();

There is no set_Prop method to override, and you can't override a method that doesn't exist.

ng5000
True, but I can add a new virtual method, right?
Vilx-
not sure what you mean, but you could add a virtual method as a 'set' property which will be converted to a virtual set method...
ng5000
A: 

You can hide the base class implementation by using the 'new' keyword in your derived class. The following should compile succesfully:

class A
{
    public virtual string prop
    {
        get
        {
            return "A";
        }
    }
}
class B : A
{
    private string X;
    public new string prop
    {
        get
        {
            return X;
        }
        set
        {
            X = value;
        }
    }
}
Sam
Introducing a different backing field is usually risky, though... from the black-box perspective, class A could have a field etc as the underlying implementation, and any usage of that field would be suspect...
Marc Gravell
Agree, I'm not fond of this code...
Sam
+1  A: 

No, this is not possible. Unfortunately you can not even override and change the accessor level (from protected to public for example), as documented on MSDN. I would recommend that you consider restructuring the code/class slightly and look for an alternative way to accomplish this task such as declaring the set accessor with the protected modifier using a SetProperty method in the derived class.

Noldorin
A: 

Introducing a new field smacks of messy. And either way you need to be careful not to break polymorphism and inheritance (what if the base-class talks to the private field?).

With regard to adding a new accessor while overriding; the simple answer is "no, you can't". When you override, you can only impact the existing accessors, since that is what is defined in the virtual-table for the member (an overridden member is still "owned" by the base/declaring class, not the overriding class).

One option (not ideal) is to re-declare the property, but you would still need a way to talk down to the base-class. So if the accessor in the base-class was protected:

class A
{
    public string prop
    {
        get;
        protected set;
    }
}
class B : A
{
    public new string prop
    {
        get { return base.prop; }
        set { base.prop = value; }
    }
}
Marc Gravell