【发布时间】:2014-04-08 06:59:20
【问题描述】:
更新:这个问题已经过修改,使其更清晰。下面的答案似乎反映了这种方法效果很好。希望这个问题可以帮助需要将get 或set 添加到现有属性的人。
今天遇到一个问题,我需要用get 和set 覆盖基类的get-only 属性。目前的共识似乎是这是不可能的,但我认为我找到了一种方法。
一般的想法是创建一个new 属性而不是直接使用旧的override 属性,然后我们创建一个桥接方法,该方法overrides 旧的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's 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 继承的类,同时还可以在setter 中进行覆盖。这是正确的吗?
【问题讨论】:
-
实际上这会起作用,但理论上这是不正确的,正确的做法是在抽象类A中添加setter。
-
@Consult Yarla:基类
A具有其他无法设置属性的继承类。如果基类允许设置属性,那么对于不需要它的类,就必须有一个 setter 的虚拟实现。 -
以前的问题,人们讨论了为什么用 getter/setter 覆盖仅 getter 的属性是不可能的:stackoverflow.com/questions/82437
-
可以使用类似的方法来覆盖具有派生类型的方法:stackoverflow.com/questions/22313097
标签: c# overriding readonly setter getter