2017-02-16 20 views
2

RebarクラスがReinforcementクラスから派生し、RebarShapeクラスがReinforcementShapeクラスを継承する場合、C#コードでは、ベースクラスのReinforcementShapeプロパティをRebarShapeクラスでオーバーライドすることはできますか?派生クラスを持つ基本クラスのオーバーライドプロパティ

public class ReinforcementShape 
    { 
    } 

    public class RebarShape : ReinforcementShape 
    { 
    } 

    public class Reinforcement 
    { 
     public ReinforcementShape Shape { get; set; } 
    } 


    public class Rebar : Reinforement 
    { 
     // I want to override the Shape property 
     // but with its derived class which is RebarShape 

     // override the base property somehow! 
     public RebarShape Shape { get; set; } 
    } 

更新:

現在の実装の何が問題になっているのですか?ベースで

派生で

public virtual ReinforcementShape Shape { get; set; } 

public new RebarShape Shape { get; set; } 
+1

プロパティをオーバーライドして戻り値の型を変更することはできません。 –

答えて

4

あなたはジェネリックでこれを行うことができ、基本クラスのメンバーオーバーライドする必要はありません:あなたは簡単にReBarのインスタンスを作成し、アクセスすることができます今

public class Reinforcement<T> where T: ReinforcementShape 
{ 
    public <T> Shape { get; set; } 
} 

public class Rebar : Reinforement<RebarShape> 
{ 
} 

をそのインスタンスであるShape -property RebarShapeの:

var r = new Rebar(); 
r.Shape = new RebarShape(); 

そのプロパティにReinforcementShapeのインスタンスを割り当てるattempはコンピが発生しますこの時点でRebarShapeだけが有効です。

編集:あなたの編集ごとに。メンバをオーバーライドできるのは、戻り値ではなく、実装をオーバーライドすることだけです。したがって、virtualを使用すると、あなたの場合は何もしません。しかし、R.Rusevが既に言及したように、派生メンバーにはnewキーワードが必要です。これは基本クラスからのものと同じ名前の全く新しいメンバーを実際に提供します。しかし実際にはそれは前者のものと共通していない全く異なるメンバーです。しかし、あなたが次を書くとき

Reinforcement r = new Rebar(); 
// assign value to Shape 
var shape = r.Shape; 

元の実装は、あなたの新しいものではなく、使用されます。従ってshapeは、RebarShapeの代わりにReinforcementShapeとなります。これを回避する唯一の方法は、最初の場所でRebarとしてrを宣言することです:

Rebar r = new Rebar(); 
// assign value to Shape 
var shape = r.Shape; 

しかし、これはまた、アプリケーションのすべてのユーザに、多分自分自身に非常に紛らわしいです。私は一般的にそのキーワードを使用することをお勧めしません。最初のアプローチを使います。

+0

あなたは私の更新を見ていただけますか? – Vahid

+0

残念ながら、ジェネリックは使用できません。私はこれらのクラスのいくつかのプロパティに対してこれを行う必要があるからです。 – Vahid

+0

@Vahid:他のプロパティを質問に追加する必要があります。一般に、ジェネリックスはそれを行うためのよりよい方法です( 'new'キーワードの答えと比較して) – phifi

1

あなたはそれを行うにはnewキーワードを使用することができます。したがって、Rebarクラスの定義は次のようになります。

public class Rebar : Reinforement 
{ 
    public new RebarShape Shape 
    { 
     get { return (RebarShape)base.Shape; } 
     set { base.Shape = value; } 
    } 
} 
+5

'new'キーワードは基底クラスの実装をオーバーライドしませんが、*非表示にします。とにかく、基本クラスの変数として派生クラスのインスタンスを使用する場合、キーワードを使用しても、元のメンバーが使用され、新しいクラスは使用されません。 – HimBromBeere

+0

ありがとうございます。基本クラスの実装を見せてください。私は基底クラスでも設定できるようにしたい。 – Vahid

+0

@Vahid基本クラスは同じです。 –

関連する問題