2009-05-20 10 views
9

私は、共通の祖先がさまざまなプロパティの設定に関係するすべてのロジックを担当するクラスのセットを作成しようとしています。子孫はプロパティのアクセスを変更するかどうか彼らは特定の子孫に必要です。プロパティのアクセス修飾子を増やす方法

私は以下のようにそれを実行しようコンパイラエラーを取得:

「『保護された』オーバーライドする場合は、アクセス修飾子を変更することはできませんがメンバー継承された」私がしようとしているものを達成する方法はあります行う?おかげ

public class Parent 
{ 
    private int _propertyOne; 
    private int _propertyTwo; 

    protected virtual int PropertyOne 
    { 
      get { return _propertyOne; } 
      set { _propertyOne = value; } 
    } 

    protected virtual int PropertyTwo 
    { 
      get { return _propertyTwo; } 
      set { _propertyTwo = value; } 
    } 
} 

public class ChildOne : Parent 
{ 
    public override int PropertyOne // Compiler Error CS0507 
    { 
     get { return base.PropertyOne; } 
     set { base.PropertyOne = value; } 
    } 
    // PropertyTwo is not available to users of ChildOne 
} 

public class ChildTwo : Parent 
{ 
    // PropertyOne is not available to users of ChildTwo 
    public override int PropertyTwo // Compiler Error CS0507 
    { 
     get { return base.PropertyTwo; } 
     set { base.PropertyTwo = value; } 
    } 
} 

答えて

11

は、次のように親の保護されたプロパティを非表示にするには、「新」の代わりに「オーバーライド」を使用してこれを行うことができます。

public class ChildOne : Parent 
{ 
    public new int PropertyOne // No Compiler Error 
    { 
     get { return base.PropertyOne; } 
     set { base.PropertyOne = value; } 
    } 
    // PropertyTwo is not available to users of ChildOne 
} 

public class ChildTwo : Parent 
{ 
    // PropertyOne is not available to users of ChildTwo 
    public new int PropertyTwo 
    { 
     get { return base.PropertyTwo; } 
     set { base.PropertyTwo = value; } 
    } 
} 
+2

OOPS .. Seconds faster :) ..とにかくnewを使うのはオーバーライドと同じではありません。 newは親メンバーを隠し、これはもはや多態性ではありません。 – Galilyou

+0

@José、私が必要としてくれてありがとう。 – WileCau

2

NO。これはあなたがアクセス権を変更することはできませんもはや仮想/上書き関係(すなわちなし多型の呼び出し)

+0

@ 7alwagy、ありがとう。私の場合、仮想/オーバーライドは関係ありません。私は基本プロパティをオーバーライドする必要があると思っています。 '上書き'の代わりに '新しい'を使用すると、そのトリックが実行されます。 – WileCau

5

ですが、あなたは再宣言することができます。それでも、あなたはあなたの

public class ChildTwo: Praent { 
    public new int PropertyTwo { 
     // do whatever you want 
    } 
} 

PSと継承されたプロパティを非表示にすることができますより大きなアクセスを持つメンバー:

public new int PropertyOne 
{ 
    get { return base.PropertyOne; } 
    set { base.PropertyOne = value; } 
} 

は、問題はこれが異なるPropertyOneであるということです、そして予想通り仮想継承/は動作しない場合があります。上記の場合(ここではbase.*と呼びますが、新しいメソッドは仮想ではありません)、これはおそらく問題ありません。あなたはこの上に本物の多型が必要な場合は、中間クラスを導入することなく、それ(私の知る限り)を行うことはできません(同じタイプで同じメンバーあなたがすることができませんnewoverride以来):

public abstract class ChildOneAnnoying : Parent { 
    protected virtual int PropertyOneImpl { 
     get { return base.PropertyOne; } 
     set { base.PropertyOne = value; } 
    } 
    protected override int PropertyOne { 
     get { return PropertyOneImpl; } 
     set { PropertyOneImpl = value; } 
    } 
} 
public class ChildOne : ChildOneAnnoying { 
    public new int PropertyOne { 
     get { return PropertyOneImpl; } 
     set { PropertyOneImpl = value; } 
    } 
} 

上記の重要な点は、依然としてオーバーライドする単一の仮想メンバーがあることです:PropertyOneImpl

+0

@Marc、私は仮想/オーバーライドが必要だと思ったのでおそらく私はものを混乱させましたが、明らかにこの場合は私はしません。私は多態性でそれを行う必要があるときにあなたの答えへのリンクを保持します:)説明とサンプルコードをありがとう。 – WileCau

関連する問題