Frage

Ich bin auf der Suche nach einem Weg, um effektiv zu verstecken geerbten member.Ich habe eine Bibliothek von Klassen, die Vererbung von gemeinsamen Basisklassen.Einige der neueren abgeleiteten Klassen Erben abhängigkeitseigenschaften, die sich verkümmerten und kann ein wenig verwirrend sein, wenn mit IntelliSense oder durch die Verwendung der Klassen in einem visuellen designer.

Diese Klassen sind alle Steuerelemente, die sind geschrieben kompiliert werden, um entweder WPF oder Silverlight 2.0.Ich weiß über ICustomTypeDescriptor und ICustomPropertyProvider,, aber ich bin ziemlich sicher, dass diejenigen, die nicht verwendet werden können, die in Silverlight.

Es ist nicht so sehr eine funktionale Frage, wie ein usability-Problem.Was soll ich tun?

Update

Einige der Eigenschaften, die ich würde wirklich gerne verstecken kommen von Vorfahren, die sind nicht mein eigenes, und weil von einem bestimmten Werkzeug bin ich entwerfen für, ich kann das nicht Mitglied versteckt sich die new Betreiber.(Ich weiß, es ist lächerlich)

War es hilfreich?

Lösung

Überschreiben Sie wie Michael Schlägt über und um zu verhindern, dass Leute aus der Verwendung der überschrieben (sp?) Methoden, markieren Sie Sie als erledigt:

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

Wenn die zweite parm auf true gesetzt ist, wird ein compiler-Fehler werden generiert, wenn jemand versucht, rufen Sie die Methode und die Zeichenfolge in der ersten parm ist die Botschaft.Wenn parm2 ist falsch, nur eine compiler-Warnung generiert wird.

Andere Tipps

Sie können zwar nicht verhindern, die Verwendung von denen geerbt Mitglieder-nach meinem wissen-Sie sollten in der Lage sein, Sie zu verstecken, von IntelliSense-mit der EditorBrowsableAttribute:

Using System.ComponentModel;

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

Edit: Gerade gesehen, das in der Dokumentation Kommentaren, die macht es irgendwie unbrauchbar für diesen Zweck:

Es gibt einen auffälligen Hinweis, der besagt, dass das Attribut "nicht unterdrücken Mitglieder aus einer Klasse in derselben assembly".Das stimmt aber nicht vollständig.Eigentlich ist das Attribut nicht unterdrücken Mitglieder aus einer Klasse in der gleichen Lösung.

Eine mögliche Sache, die Sie tun können, ist, die dieses Objekt enthalten, anstatt sich von den anderen in der Klasse.Dies gibt Ihnen die größte Flexibilität in Bezug auf die offenlegen, was Sie möchten zu setzen, aber wenn du unbedingt das Objekt dieses Typs ist es nicht die ideale Lösung (aber Sie könnten setzen Sie das Objekt von einem getter).

Also:

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

Wird zu:

public class MyClass
{
    private BaseClass baseClass;

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

Oder:

public class MyClass
{
    private BaseClass baseClass;

    public BaseClass BaseClass
    {
        get
        {
            return baseClass;
        }
    }
}

Ich denke, Sie sind am wenigsten hackish Weg ist zu berücksichtigen Zusammensetzung im Gegensatz zur Vererbung.

Oder, Sie könnte eine Schnittstelle erstellen, hat die Mitglieder, die Sie wollen, müssen Ihre abgeleiteten Klasse implementieren, die Schnittstelle und das Programm auf die Schnittstelle.

Ich weiß, dass es mehrere Antworten auf diese, und es ist ziemlich alt, aber die einfachste Methode, dies zu tun ist nur erklären, sondern Sie als new private.

Betrachten Sie ein Beispiel, das ich gerade arbeite, wo ich eine API, die zur Verfügung stellt, jede Methode in einer 3rd-party-DLL.Ich habe Ihre Methoden, aber ich möchte an einem .Net-Eigenschaft anstelle der "getThisValue" und "setThisValue" - Methode.So baute ich eine zweite Klasse, Erben der ersten, eine Eigenschaft, die verwendet die get-und set-Methoden, und dann überschreiben Sie die ursprüngliche get-und set-Methoden als private.Sie sind immer noch verfügbar für jeden, der bauen zu wollen, etwas anderes über Sie, aber wenn Sie nur möchten, verwenden Sie die engine die ich Baue, dann werden Sie in der Lage sein zu verwenden von Eigenschaften anstelle von Methoden.

Mit der double-Klasse-Methode ruft befreien von Einschränkungen nicht in der Lage zu bedienen die new Erklärung zum ausblenden der Mitglieder.Sie kann einfach nicht verwenden override wenn die Mitglieder gekennzeichnet sind, die als virtuelle.

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; }
}

Jetzt valueEnum ist sowohl für Klassen, aber nur die Eigenschaft ist sichtbar im APIUsageClass Klasse.Die APIClass-Klasse ist immer noch für Menschen, die wollen zu verlängern die original-API oder verwenden Sie es in einer anderen Weise, und die APIUsageClass ist verfügbar, für diejenigen, die wollen etwas einfach.

Letztlich, was ich tun werde, ist, dass die APIClass innere, und nur dann aussetzen, meinen geerbten Klasse.

Vollständig ausblenden, und die Marke nicht zu verwenden, einschließlich intellisense, die ich glaube, ist, was die meisten Leser erwarten ...

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

Getestet habe ich alle vorgeschlagenen Lösungen und Sie nicht wirklich verbergen neue Mitglieder.

Aber diese MACHT:

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

Aber in code-behide es ist immer noch zugänglich, so fügen Sie Veraltete Attribut

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

Sie können eine Schnittstelle

    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();
        }
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top