質問

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

これらのクラスはすべて、WPF または Silverlight 2.0 用にコンパイルされるように記述されたコントロールです。については知っています ICustomTypeDescriptor そして ICustomPropertyProvider, しかし、これらは Silverlight では使用できないことは確かです。

それは機能的な問題というよりも、使いやすさの問題です。どうすればいいですか?

アップデート

本当に非表示にしたいプロパティの一部は、自分のものではない祖先に由来しており、私が設計している特定のツールのせいで、 new オペレーター。(わかっています、それはばかげています)

役に立ちましたか?

解決

マイケルが提案するようにそれらをオーバーライドします その上 また、オーバーライドされた (sp?) メソッドを使用できないようにするには、それらのメソッドを廃止済みとしてマークします。

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

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

他のヒント

私の知る限り、これらの継承されたメンバーの使用を防ぐことはできませんが、 EditorBrowsable属性:

Using System.ComponentModel;

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

編集: ドキュメントのコメントでこれを見たところ、この目的には役に立たないものになっています。

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

実行できる可能性の 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;
        }
    }
}

最もハック的でない方法は、継承ではなく構成を考慮することだと思います。

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

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

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

ダブルクラスメソッドを使用すると、クラスを使用できないという制限がなくなります。 new メンバーを非表示にする宣言。ただ使えないだけです 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 を内部化し、継承したクラスのみを公開することになります。

ほとんどの読者が期待していると思われるインテリセンスを含め、完全に非表示にし、使用しないようにマークすること...

[Obsolete("Not applicable in this class.")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]

提案された解決策をすべてテストしましたが、実際には新しいメンバーを隠すものではありませんでした。

しかし、これは次のことを行います。

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

ただし、code-behide ではまだアクセスできるため、Obsolete 属性も追加します。

[Obsolete("This property is not supported in this class", true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}

インターフェイスを使用できます

    public static void Main()
    {
        NoRemoveList<string> testList = ListFactory<string>.NewList();

        testList.Add(" this is ok ");

        // not ok
        //testList.RemoveAt(0);
    }

    public interface NoRemoveList<T>
    {
        T this[int index] { get; }
        int Count { get; }
        void Add(T item);
    }

    public class ListFactory<T>
    {
        private class HiddenList: List<T>, NoRemoveList<T>
        {
            // no access outside
        }

        public static NoRemoveList<T> NewList()
        {
            return new HiddenList();
        }
    }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top