Можно ли добавить метод доступа к свойству в .NET, переопределив его?

Можно ли сделать что-то подобное?

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;
        }
    }
}

То есть базовый класс предоставляет виртуальное свойство только с методом доступа GET, но дочерний класс переопределяет GET и также предоставляет SET.

Текущий пример не компилируется, но, возможно, я что-то здесь упускаю.

Добавлено: Чтобы уточнить, нет, я не хочу переопределять с новым. Я хочу добавить новый аксессуар. Я знаю, что этого не было в базовом классе, поэтому его нельзя переопределить. Хорошо, позвольте мне объяснить, как это выглядело бы без синтаксического сахара:

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;
    }
}

person Vilx-    schedule 13.02.2009    source источник
comment
Что касается редактирования - простой ответ: нет: вы не можете.   -  person Marc Gravell    schedule 13.02.2009
comment
Отредактируйте это в своем ответе, и я приму это. :)   -  person Vilx-    schedule 13.02.2009


Ответы (4)


Нет, это невозможно. К сожалению, вы даже не можете переопределить и изменить уровень доступа (например, с защищенного на общедоступный), как описано на MSDN. Я бы порекомендовал вам подумать о небольшой реструктуризации кода/класса и поискать альтернативный способ выполнения этой задачи, например объявить метод доступа set с модификатором protected с помощью метода SetProperty в производном классе.

person Noldorin    schedule 13.02.2009

Нет, нет никакого способа сделать это. Подумайте о том, как обрабатывается синтаксический сахар вашего виртуального свойства, то есть он преобразуется в:

public virtual string get_prop();

Нет метода set_Prop для переопределения, и вы не можете переопределить несуществующий метод.

person ng5000    schedule 13.02.2009
comment
не уверен, что вы имеете в виду, но вы можете добавить виртуальный метод в качестве свойства "set", которое будет преобразовано в метод виртуального набора... - person ng5000; 13.02.2009

Вы можете скрыть реализацию базового класса, используя ключевое слово new в производном классе. Следующее должно успешно скомпилироваться:

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;
        }
    }
}
person Sam Holloway    schedule 13.02.2009
comment
Однако введение другого резервного поля обычно рискованно... с точки зрения черного ящика класс A может иметь поле и т. д. в качестве базовой реализации, и любое использование этого поля будет подозрительным... - person Marc Gravell; 13.02.2009

Представление нового поля попахивает беспорядком. И в любом случае вам нужно быть осторожным, чтобы не нарушить полиморфизм и наследование (что, если базовый класс общается с приватным полем?).

Что касается добавления нового средства доступа при переопределении; простой ответ "нет, вы не можете". Когда вы переопределяете, вы можете повлиять только на существующие методы доступа, поскольку это то, что определено в виртуальной таблице для члена (переопределенный член по-прежнему «принадлежит» базовому/декларирующему классу, а не классу переопределения).

Один из вариантов (не идеальный) - повторно объявить свойство, но вам все равно нужен способ поговорить с базовым классом. Итак, если аксессор в базовом классе был protected:

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