45

継承されたメンバーを効果的に隠す方法を探しています。共通の基本クラスから継承するクラスのライブラリがあります。最近の子孫クラスの一部は、痕跡となった依存関係プロパティを継承しており、IntelliSenseを使用したり、ビジュアルデザイナーでクラスを使用したりすると、少し混乱する可能性があります。

これらのクラスはすべて、WPFまたはSilverlight2.0用にコンパイルされるように作成されたコントロールです。ICustomTypeDescriptorとについては知ってICustomPropertyProviderいますが、Silverlightでは使用できないと確信しています。

これは、ユーザビリティの問題ほど機能的な問題ではありません。私は何をすべきか?

アップデート

私が本当に隠したいプロパティのいくつかは、私自身ではない祖先からのものであり、私が設計している特定のツールのために、newオペレーターと一緒にメンバーを隠すことはできません。(私は知っている、それはばかげている)

4

9 に答える 9

37

上記のMichaelSuggestsのようにそれらをオーバーライドし、オーバーライドされた(sp?)メソッドを使用しないようにするには、それらを廃止としてマークします。

[Obsolete("These are not supported in this class.", true)]
public override  void dontcallmeanymore()
{
}

2番目のパラメーターがtrueに設定されている場合、誰かがそのメソッドを呼び出そうとすると、コンパイラエラーが生成され、最初のパラメーターの文字列がメッセージになります。parm2がfalseの場合、コンパイラ警告のみが生成されます。

于 2008-08-04T20:14:30.547 に答える
20

私の知る限り、これらの継承されたメンバーの使用を防ぐことはできませんが、 EditorBrowsableAttributeを使用してIntelliSenseからそれらを隠すことができるはずです。

Using System.ComponentModel;

[EditorBrowsable(EditorBrowsableState.Never)]
private string MyHiddenString = "Muahahahahahahahaha";

編集:ドキュメントのコメントでこれを見ただけで、この目的には少し役に立たなくなります:

この属性は「同じアセンブリ内のクラスのメンバーを抑制しない」という顕著な注記があります。それは真実ですが、完全ではありません。実際、この属性は同じソリューションのクラスのメンバーを抑制しません。

于 2008-08-04T19:19:33.013 に答える
14

実行できる可能性のあることの1つは、他のクラスから拡張するのではなく、オブジェクトを含めることです。これにより、公開したいものを公開するという点で最も柔軟性がありますが、オブジェクトをそのタイプにする必要がある場合は、理想的なソリューションではありません(ただし、ゲッターからオブジェクトを公開することはできます)。

したがって:

public class MyClass : BaseClass
{
    // Your stuff here
}

になる:

public class MyClass
{
    private BaseClass baseClass;

    public void ExposeThisMethod()
    {
        baseClass.ExposeThisMethod();
    }
}

または:

public class MyClass
{
    private BaseClass baseClass;

    public BaseClass BaseClass
    {
        get
        {
            return baseClass;
        }
    }
}
于 2008-08-04T19:22:48.903 に答える
8

私はあなたが最もハックな方法ではないと思いますが、継承ではなく構成を検討することです。

または、必要なメンバーを持つインターフェイスを作成し、派生クラスにそのインターフェイスを実装させ、インターフェイスに対してプログラムすることもできます。

于 2008-08-04T19:19:34.977 に答える
4

これにはいくつかの答えがあり、今ではかなり古いですが、これを行う最も簡単な方法は、それらを として宣言することnew privateです。

私が現在取り組んでいる例を考えてみましょう。ここでは、サード パーティの DLL のすべてのメソッドを利用できるようにする API があります。それらのメソッドを使用する必要がありますが、「getThisValue」および「setThisValue」メソッドの代わりに .Net プロパティを使用したいと考えています。そこで、2 番目のクラスを作成し、最初のクラスを継承して、get メソッドと set メソッドを使用するプロパティを作成し、元の get メソッドと set メソッドをプライベートとしてオーバーライドします。それらに何か違うものを構築したい人はまだ利用できますが、私が構築しているエンジンを使用したいだけであれば、メソッドの代わりにプロパティを使用できるようになります。

newdouble クラス メソッドを使用すると、宣言を使用してメンバーを非表示にできないという制限が取り除かれます。overrideメンバーが仮想としてマークされている場合は、単に使用できません。

public class APIClass
{
    private static const string DllName = "external.dll";

    [DllImport(DllName)]
    public extern unsafe uint external_setSomething(int x, uint y);

    [DllImport(DllName)]
    public extern unsafe uint external_getSomething(int x, uint* y);

    public enum valueEnum
    {
        On = 0x01000000;
        Off = 0x00000000;
        OnWithOptions = 0x01010000;
        OffWithOptions = 0x00010000;
    }
}

public class APIUsageClass : APIClass
{
    public int Identifier;
    private APIClass m_internalInstance = new APIClass();

    public valueEnum Something
    {
        get
        {
            unsafe
            {
                valueEnum y;
                fixed (valueEnum* yPtr = &y)
                {
                    m_internalInstance.external_getSomething(Identifier, yPtr);
                }
                return y;
            }
        }
        set
        {
            m_internalInstance.external_setSomething(Identifier, value);
        }
    }

    new private uint external_setSomething(int x, float y) { return 0; }
    new private unsafe uint external_getSomething(int x, float* y) { return 0; }
}

現在、valueEnum は両方のクラスで使用できますが、プロパティのみが APIUsageClass クラスで表示されます。APIClass クラスは、元の API を拡張したり、別の方法で使用したりしたい人のために引き続き利用できます。APIUsageClass は、より単純なものを望む人のために利用できます。

最終的には、APIClass を内部化し、継承したクラスのみを公開します。

于 2010-12-08T20:54:44.970 に答える
1

提案されたすべてのソリューションをテストしましたが、実際には新しいメンバーを隠していません。

しかし、これは行います:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}

ただし、分離コードでは引き続きアクセスできるため、廃止された属性も追加します

[Obsolete("This property is not supported in this class", true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}
于 2012-05-23T10:19:32.310 に答える