Ausblenden von geerbten Mitglieder

stimmen
34

Ich bin auf der Suche nach einem Weg , um effektiv geerbten Mitglieder zu verstecken. Ich habe eine Bibliothek von Klassen , die von gemeinsamen Basisklassen erben. Einige der neueren abgeleiteten Klassen erben Abhängigkeitseigenschaften , die verkümmerten worden und kann ein wenig verwirrend sein , wenn mit IntelliSense oder die Klassen in einem visuellen Designer.

Diese Klassen sind alle Steuerelemente , die geschrieben werden , entweder für WPF oder Silverlight 2.0 kompiliert werden. Ich kenne ICustomTypeDescriptorund ICustomPropertyProvider, aber ich bin ziemlich sicher , die können nicht in Silverlight verwendet werden.

Es ist nicht so sehr ein funktionelles Problem als Usability-Problem. Was soll ich machen?

Aktualisieren

Einige der Eigenschaften , die ich wirklich von den Vorfahren verstecken kommen möchte, die nicht meine eigenen und wegen eines bestimmten Werkzeugs , das ich für mich entwerfen, kann ich Mitglied nicht mit dem Verstecken newBetreiber. (Ich weiß, es ist lächerlich)

Veröffentlicht am 04/08/2008 um 20:13
quelle vom benutzer
In anderen Sprachen...                            


8 antworten

stimmen
32

Außer Kraft setzen sie wie Michael Schlägt oben und zu verhindern , dass Menschen aus der Verwendung der Überschriebene Methoden, markieren Sie sie als veraltet (sp?):

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

Wenn die zweite parm auf wahr gesetzt ist, wird ein Compiler-Fehler erzeugt werden, wenn jemand diese Methode aufzurufen versucht und die Zeichenfolge in dem ersten parm die Nachricht ist. Wenn parm2 falsch ist, wird nur eine Compiler-Warnung generiert werden.

Beantwortet am 04/08/2008 um 21:14
quelle vom benutzer

stimmen
16

Während Sie nicht Verwendung dieser geerbten Mitglieder meines Wissens verhindern können, sollten Sie in der Lage sein , sie von IntelliSense zu verstecken , die mit EditorBrowsableAttribute :

Using System.ComponentModel;

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

Edit: Gerade gesehen , dies in der Dokumentation Kommentaren, die zu diesem Zweck es irgendwie nutzlos macht:

Es gibt einen gut sichtbaren Hinweis, das besagt, dass dieses Attribut „nicht unterdrückt Mitglieder aus einer Klasse in der gleichen Assembly“. Das ist wahr, aber nicht vollständig. Eigentlich ist das Attribut nicht Mitglieder von einer Klasse in der gleichen Lösung unterdrücken.

Beantwortet am 04/08/2008 um 20:19
quelle vom benutzer

stimmen
13

Ein mögliches, was man tun kann, ist das Objekt enthält, anstatt von der anderen Klasse zu erweitern. Dies gibt Ihnen die größte Flexibilität in Bezug auf die Belichtung, was Sie machen möchten, aber wenn Sie unbedingt das Objekt benötigen dieses Typs zu sein, es nicht die ideale Lösung ist (aber könnte man das Objekt aus einem Getter aussetzen).

So:

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

Wird:

public class MyClass
{
    private BaseClass baseClass;

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

Oder:

public class MyClass
{
    private BaseClass baseClass;

    public BaseClass BaseClass
    {
        get
        {
            return baseClass;
        }
    }
}
Beantwortet am 04/08/2008 um 20:22
quelle vom benutzer

stimmen
8

Ich glaube, du bist am besten mindestens hackish Weg Zusammensetzung zu prüfen, im Gegensatz zu der Vererbung.

Oder könnten Sie eine Schnittstelle erstellen, die die Mitglieder hat Sie wollen, müssen Sie Ihre abgeleitete Klasse, die eine Schnittstelle implementieren, und das Programm gegen die Schnittstelle.

Beantwortet am 04/08/2008 um 20:19
quelle vom benutzer

stimmen
3

Um vollständig zu verstecken und markieren nicht zu verwenden, einschließlich IntelliSense die meiner Meinung nach ist das, was die meisten Leser erwarten ...

[Obsolete("Not applicable in this class.")] 
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
Beantwortet am 24/06/2013 um 20:50
quelle vom benutzer

stimmen
3

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

Betrachten wir ein Beispiel Zur Zeit arbeite ich an, wo ich eine API, die jede Methode in einem 3rd-Party-DLL zur Verfügung stellt. Ich muss ihre Methoden nehmen, aber ich möchte eine .Net-Eigenschaft verwendet wird, anstelle eines „getThisValue“ und „setThisValue“ -Methode. So baue ich eine zweite Klasse, erbt die ersten, eine Eigenschaft machen, die die Get- und Set-Methoden verwendet, und dann die ursprünglichen get außer Kraft setzen und Set-Methoden als privat. Sie sind immer noch für jedermann verfügbar zu wollen, etwas anderes auf sie bauen, aber wenn sie nur den Motor verwenden will ich baue, dann werden sie in der Lage sein, Objekte zu verwenden, anstatt von Methoden.

Mit Hilfe der Doppelklassenmethode wird von Beschränkungen befreit auf nicht in der Lage , die verwenden newErklärung , die Mitglieder zu verstecken. Sie können einfach nicht verwenden , overridewenn die Mitglieder als virtuelle gekennzeichnet sind.

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 ist valueEnum für beiden Klassen zur Verfügung, sondern nur die Eigenschaft ist sichtbar in der APIUsageClass Klasse. Die APIClass Klasse ist immer noch für Menschen, die die Original-API erweitern wollen oder es auf eine andere Art und Weise zu verwenden, und die APIUsageClass ist für diejenigen, die etwas einfacher wollen.

Letztlich, was ich tun ist, um die APIClass internen machen, und nur meine vererbten Klasse aussetzen.

Beantwortet am 08/12/2010 um 21:54
quelle vom benutzer

stimmen
1

Getestet habe ich alle vorgeschlagenen Lösungen und sie nicht wirklich neue Mitglieder verstecken.

Aber dies tut:

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

Aber in Code-behide ist es immer noch zugänglich, fügen Sie so auch Veraltet Attribut

[Obsolete("This property is not supported in this class", true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{ 
    get { return _myHiddenProperty; }
}
Beantwortet am 23/05/2012 um 11:19
quelle vom benutzer

stimmen
0

Sie können eine Schnittstelle verwenden

    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();
        }
    }
Beantwortet am 13/11/2017 um 00:24
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more