这是可能的
文艺青年最爱的 - 你可以重写一个只能获得法与制定者,如果你想。基本上就是:
创建一个new
具有相同名称的a get
和a 的属性set
。
如果您不执行其他任何操作,则在get
通过其基类型调用派生类时,仍将调用旧方法。要解决此问题,请添加一个abstract
用于override
旧get
方法的中间层,以强制其返回新get
方法的结果。
这使我们能够使用get
/ 覆盖属性,set
即使它们在基本定义中缺少属性也是如此。
作为奖励,您还可以根据需要更改退货类型。
在所有情况下,都可以根据需要保留相同的返回类型。为了简单起见,以下示例使用相同的返回类型。
情况:既有get
属性
您有一些无法修改的类结构。也许它只是一个类,或者它是一个预先存在的继承树。无论如何,您都想向set
属性添加方法,但不能这样做。
public abstract class A // Pre-existing class; can't modify
{
public abstract int X { get; } // You want a setter, but can't add it.
}
public class B : A // Pre-existing class; can't modify
{
public override int X { get { return 0; } }
}
问题:无法override
在get
-only与get
/set
您想override
使用get
/ set
属性,但无法编译。
public class C : B
{
private int _x;
public override int X
{
get { return _x; }
set { _x = value; } // Won't compile
}
}
解决方案:使用abstract
中间层
虽然您不能直接override
使用get
/ set
属性,但可以:
创建一个具有相同名称的new
get
/ set
属性。
override
旧get
方法与新get
方法的访问者一起确保一致性。
因此,首先编写abstract
中间层:
public abstract class C : B
{
// Seal off the old getter. From now on, its only job
// is to alias the new getter in the base classes.
public sealed override int X { get { return this.XGetter; } }
protected abstract int XGetter { get; }
}
然后,编写不会更早编译的类。这次将编译,因为您实际上不是override
在使用get
-only属性;相反,您将使用new
关键字替换它。
public class D : C
{
private int _x;
public new virtual int X { get { return this._x; } set { this._x = value; } }
// Ensure base classes (A,B,C) use the new get method.
protected sealed override int XGetter { get { return this.X; } }
}
结果:一切正常!
显然,这按预期工作D
。
var test = new D();
Print(test.X); // Prints "0", the default value of an int.
test.X = 7;
Print(test.X); // Prints "7", as intended.
一切仍然有效-AS-目标观察时,D
它的基类之一,例如A
或B
。但是,它起作用的原因可能不太明显。
var test = new D() as B;
//test.X = 7; // This won't compile, because test looks like a B,
// and B still doesn't provide a visible setter.
但是,的基类定义get
最终仍会被派生类的定义所覆盖get
,因此它仍然是完全一致的。
var test = new D();
Print(test.X); // Prints "0", the default value of an int.
var baseTest = test as A;
Print(test.X); // Prints "7", as intended.
讨论区
此方法允许您将set
方法添加到get
-only属性。您还可以使用它来执行以下操作:
将任何属性更改为get
-only,set
-only或get
-and- set
属性,而不管它在基类中是什么。
更改派生类中方法的返回类型。
主要缺点是要做更多的编码,并且abstract class
在继承树中增加了额外的代码。对于带有参数的构造函数,这可能会有些烦人,因为必须在中间层中复制/粘贴这些参数。