2012-01-19 47 views
2

thisのような他のスレッドを読んだが、それらは私のためには機能しませんでした。私は今にClassBの新しいオブジェクトを作成した場合、私は 継承されたメンバを非表示に継承

_shouldBeInteger, _shouldBeBool, _shouldBeDateTime; 
shouldBeInteger,shouldBeBool,shouldBeDateTime 

を取得しかし、私は、ユーザーに_variablesを非表示にする

public class ClassA 
{ 
    public string _shouldBeInteger; 
    public string _shouldBeBool; 
    public string _shouldBeDateTime; 
} 

public class ClassB : ClassA 
{ 
    public int? shouldBeInteger 
    { 
     get { return (_shouldBeInteger != null) ? Convert.ToInt32(Convert.ToDouble(_shouldBeInteger)) : new int?(); } 
     set { _shouldBeInteger = Convert.ToString(value); } 
    } 

    //... same thing with datetime etc. 


} 

は、私は2つのクラスを得ました。 ClassBでそれらをプライベートに設定すると、それらがオーバーライドされますが、文字列値を解析するためにはそれらにアクセスする必要があります。

更新

主に、彼らは書き込み可能でなければならない理由であるクラスC充填ClassAs'の値は、あります。そこに私が動作する方法を変更するための方法はありませんが、私はにClassAのコントロールに完全だとClassBの

ClassC //not changeAble for me 
{ 
//infomagic filling values of ClassA  
} 

にClassAのプログラマは奇妙で、それを生成しているため、民間への変数は動作しませんにClassAの設定方法。

ソリューション

にClassAがinheritated以外のクラスに読める書き込み可能である必要がありますが、ないので、私は最終的に、この得た:ClassBのは与えることなく、theeseの特性で動作するようになり

ClassA 
{ 
    public string _shouldBeInteger { protected get; set; } 
    //and so on 
} 

を彼らは外にいる。 インテリセンスはまだそれらを示していますが、使用して検討するかもしれない:

[EditorBrowsable(EditorBrowsableState.Never)] 

はそれを解決します。

ありがとうございます。

+0

あなたがプライベートフィールドを設定すると動作しません言ったとき、彼らは公共である必要はないか、仕事を保護するのでしょうか? –

+0

アンダースコアの接頭辞は 'public members'のものではなく、' private members'の標準です – gdoron

+0

@ gdoronのコメントをちょっと吟味するだけで、アンダースコアプレフィックスはCLSに準拠していないので標準ではありませんが、CLS準拠の心配はありません。したがって、CLS準拠の警告では最終的なリリースには適していないとの警告が表示されます。 –

答えて

8

私はあなたが使用して問題を解決することができると思います。

public class ClassA 
{ 
    protected string _shouldBeInteger; 
    protected string _shouldBeBool; 
    protected string _shouldBeDateTime; 
} 

ので、これらの変数は、派生クラスにではなく、ユーザーがアクセスしています。これはあなたのためのVALIソリューションであってもよいが、試みることができる場合、私は知らない

は、ユーザーの更新後に編集あなたが思うだろうとして

public class ClassB : ClassA 
{ 
    public new int? _shouldBeInteger 
    { 
     get { return (base._shouldBeInteger != null) ? 
        Convert.ToInt32(Convert.ToDouble(base._shouldBeInteger)) : 
        new int?(); } 
     set { base._shouldBeInteger = Convert.ToString(value); } 
    } 
} 
+0

誰かがdownvoteをなぜ説明できますか?私の答えに何が間違っていますか? – Marco

+0

+1おそらくフィールド名を除いて、それらを保護することは有効な解決策です。彼らが一般公開されることを要求されていない限り、OPはそれを言っていない。 –

+0

私は彼がClassAを支配していないという質問から印象を受けたので、泣きました。それが事実でない場合は、私はアンダーバーを解除するでしょう:) – MattDavey

4

継承メンバーを隠すことができません。 newモディファイアはベースメンバーを「隠す」ために存在しますが、ベースタイプと話すときにはうまくいきません。あなたは、フィールドのアクセスレベル(好ましい方法)を変更するか、またはあなたの代わりにそれから継承するクラスをラップし、ラップクラスに委譲するための単純なパススルー方法を提供することができます

http://msdn.microsoft.com/en-us/library/435f1dw2.aspx

。これはAdapter Patternと呼ばれる:

public class ClassB 
{ 
    private ClassA _wrappedClass; 
} 

さておき、あなたの公開のフィールドは、一般的に民間分野に使用される命名規則に従っているのと同じように。

派生クラスに必要なアクセスレベルがprotectedです。メンバーが公に使用されているが同じアセンブリで使用されている場合はprotected internalを使用できます。メンバーが他のアセンブリによって公開されている場合は、リファクタリングをお勧めします。あなたがにClassAのコントロールを持っていない場合

+0

良い点、upvoted! – Marco

+1

OPの更新を見て私は私の答えを編集:あなたはどう思いますか?それは道のりだろうか? – Marco

+0

クラスをラップしてください。確かに可能です。別の方法で今見つけましたが、次回はそれを早期に考えていきます。ありがとう。 – Harry

0

、あなたはそうのようなラッパー/アダプタクラスを作成する必要があります:

public class ClassB 
{ 
    private readonly _classA = new ClassA(); 

    public int? shouldBeInteger 
    { 
     get 
     { 
      return (this._classA._shouldBeInteger != null) 
       ? Convert.ToInt32(Convert.ToDouble(this._classA._shouldBeInteger)) 
       : new int?(); 
     } 
     set 
     { 
      this._classA._shouldBeInteger = Convert.ToString(value); 
     } 
    } 
} 
+1

内部クラス名に 'ClassA'を使用しないでください...' private classA = new ClassA(); ') – Marco

+0

@Marcoあなたは正しいです、もともと私有財産でしたが、私はそれを最後の1分のフィールド:) – MattDavey

1

問題は、あなたは、基本クラスでpublicフィールドを宣言したということです。継承の多態性に違反しないように、基底クラスのパブリックなものは、すべての派生クラスでパブリックでなければなりません。それを変更することができれば、ClassBがClassAを予期しているものに渡されることは決してありません。他の人が示唆したよう

はそのため、あなたはおそらくそれらを見ることができます派生クラスを除いて、民間のようである、ベースクラスのフィールドが保護宣言することにしたいです。

ClassAの実際のインスタンスを介してアクセスする必要がある場合は、それらをプライベートとして宣言し、派生クラスがオーバーライドできる仮想パブリックプロパティを与えることができます。これにより、少なくとも、派生クラスはその振る舞いを変更することができますが、実際にはそれを隠すことはできません。

これも当てはまらない場合は、継承の代わりに合成を使用することを検討する価値があります。これは、置換原則が実際にあなたのやり方になっているためです。これは継承の基本です。 ShouldBeIntegerクラス外づけしあろう。この場合の双方に

0
public class ClassB 
{ 
    private int shouldBeInteger; 

    public int ShouldBeInteger 
    { 
     get { return shouldBeInteger; } 
     set { shouldBeInteger = value; } 
    } 

} 

OR

public class ClassB 
    { 

    public int ShouldBeInteger{ get; set; } 

    } 

は、最初のケースではプライベートに出願する

値がパブリックフィールドを介して設定することができ、クラス外づけしすることができないプライベートフィールドがありました。コンパイラが自動的にプライベートバッキングフィールドを作成し、上記と同じ

プロセスを行う第2のケースで

。これは自動実装されたプロパティです。

これがあなたを助けてくれることを願っています。

関連する問題