それが可能だ
TL; DR - あなたがしたい場合は、セッターとのget-のみのメソッドをオーバーライドすることができます。基本的には次のとおりです。
同じ名前を使用してnewa 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と/overridegetgetset
/ プロパティを使用overrideしたいのですが、コンパイルされません。getset
public class C : B
{
private int _x;
public override int X
{
get { return _x; }
set { _x = value; } // Won't compile
}
}
解決策:abstract中間層を使用する
/ プロパティを直接override使用することはできませんが、次のことができます。getset
同じ名前で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つとして表示した場合でも、すべてが意図したとおりに機能します。しかし、それが機能する理由は少し明白ではないかもしれません。AB
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、継承ツリーに余分なものがあることです。これらは中間層でコピー/貼り付けする必要があるため、パラメーターを受け取るコンストラクターではこれは少し面倒です。