Обновление: Этот вопрос был изменен, чтобы сделать его более ясным. Ниже приведенные ответы отражают, что этот метод работает хорошо. Надеюсь, этот вопрос может помочь людям, которым необходимо добавить get
или set
к существующему свойству.
В настоящее время возникает проблема, когда мне нужно переопределить свойство базового класса get
-only как с get
, так и с set
. Похоже, что нынешний консенсус заключается в том, что это невозможно, но я считаю, что нашел метод.
Общая идея состоит в том, чтобы создать свойство new
вместо прямого override
старого, затем мы создаем метод моста, который override
использует старый метод get
при вызове нового.
Ситуация
Вот некоторый код для произвольной ранее существующей структуры типа, которая не может быть изменена.
public abstract class A
{
public abstract int X { get; }
}
public class B : A
{
public override int X { get { return 0; } }
}
Проблема
Мы хотели бы написать этот код, но он не будет компилироваться.
public class C : B // won't compile: X can't have a 'set' method
{
private int _x;
public override int X { get { return _x; } set { _x = value; } }
}
Решение
В любом случае мы пишем код, который мы хотим, но мы объявляем свойство new
вместо override
, что позволяет объявить метод set
.
public class D : C // Same thing, but will compile because X is 'new'
{
private int _x;
public new virtual int X { get { return this._x; } set { this._x = value; } } // also 'virtual', unless we want to 'sealed' it.
// Bridge method provides the override functionality:
protected sealed override int XGetter { get { return this.X; } } // 'sealed' because this bridge should always refer to the new 'get' method
}
Дополнительный мостовой метод XGetter
предоставляет override
. Это приклеивается к структуре базового класса с использованием промежуточного слоя:
public abstract class C : B //abstract intermediate layer
{
// Override-and-seal the base property getter.
public sealed override int X { get { return this.XGetter; } }
// Define the bridge property for the new class to override.
protected abstract int XGetter { get; }
}
Я думаю, что D
теперь эквивалентен классу, наследующему от B
, а также может переопределять в сеттере. Правильно ли это?