それが可能だ
TL; DR - あなたがしたい場合は、セッターとのget-のみのメソッドをオーバーライドすることができます。基本的には次のとおりです。
同じ名前を使用してnew
a get
とaの両方を持つプロパティを作成しますset
。
他に何もしないget
場合、派生クラスがその基本型を通じて呼び出されると、古いメソッドが呼び出されます。これを修正するには、古いメソッドをabstract
使用override
しget
て新しいget
メソッドの結果を返すように強制する中間層を追加します。
これにより、基本定義にプロパティがなくても、get
/ set
でプロパティをオーバーライドできます。
おまけとして、必要に応じて戻り値の型を変更することもできます。
基本定義がget
-onlyの場合、より派生した戻り値の型を使用できます。
基本定義がset
-onlyの場合、あまり派生していない戻り値の型を使用できます。
基本定義がすでにget
/ set
であった場合、次のようになります。
どの場合でも、必要に応じて同じ戻り値の型を維持できます。以下の例では、簡単にするために同じ戻り値の型を使用しています。
状況:既存の- get
のみのプロパティ
変更できないクラス構造があります。たぶん、それはたった1つのクラスか、既存の継承ツリーです。いずれにせよ、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; } }
}
問題:することはできません-onlyと/override
get
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
「INGのget
のみのプロパティを。代わりに、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.
やなどD
、基本クラスの1つとして表示した場合でも、すべてが意図したとおりに機能します。しかし、それが機能する理由は少し明白ではないかもしれません。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
-と- set
に関係なく、それは、基本クラスにあったものを、プロパティ。
派生クラスのメソッドの戻り型を変更します。
主な欠点は、行うべきコーディングが多いこととabstract class
、継承ツリーに余分なものがあることです。これらは中間層でコピー/貼り付けする必要があるため、パラメーターを受け取るコンストラクターではこれは少し面倒です。