Vererbte Mitglieder verstecken

  • Ich suche nach einer Möglichkeit, vererbte Mitglieder effektiv auszublenden. Ich habe eine Bibliothek von Klassen, die von allgemeinen Basisklassen erben. Einige der neueren abgeleiteten Klassen erben Abhängigkeitseigenschaften, die als unumstritten gelten und bei Verwendung von IntelliSense oder bei Verwendung der Klassen in einem visuellen Designer etwas verwirrend sein können.

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

    Es ist weniger ein funktionales Problem als ein Usability-Problem. Was soll ich tun?

    Update

    Einige Eigenschaften, die ich wirklich verbergen möchte Ich stamme von Vorfahren, die nicht meine eigenen sind. Aufgrund eines bestimmten Tools, für das ich entworfen habe, kann ich kein Mitglied mit dem Operator new verstecken. (Ich weiß, es ist lächerlich)

    30 April 2015
    Hossein Narimani RadEric
7 answers
  • Sie können zwar die Verwendung dieser geerbten Mitglieder meines Wissens nicht verhindern, Sie sollten sie jedoch unter Verwendung von EditorBrowsableAttribute :

     Using System.ComponentModel;
    
    [EditorBrowsable(EditorBrowsableState.Never)]
    private string MyHiddenString = "Muahahahahahahahaha";
     > 
     

    Bearbeiten: Ich habe dies gerade in den Dokumentationskommentaren gesehen, was es für diesen Zweck irgendwie nutzlos macht:

    Es gibt einen prominenten Hinweis das besagt, dass dieses Attribut "Mitglieder einer Klasse in derselben Assembly nicht unterdrückt". Das ist wahr, aber nicht vollständig. Tatsächlich unterdrückt das Attribut keine Mitglieder einer Klasse in derselben Lösung.

    19 November 2009
    Michael Stum
  • Eine mögliche Sache, die Sie tun können, besteht darin, das Objekt zu enthalten, anstatt sich von der anderen Klasse zu erstrecken. Dies gibt Ihnen die größtmögliche Flexibilität hinsichtlich der Offenlegung von Informationen, die Sie freilegen möchten. Wenn Sie jedoch unbedingt benötigen, dass das Objekt von diesem Typ ist, ist es nicht die ideale Lösung (jedoch können Sie das Objekt von einem Getter aus anzeigen).

    Also:

     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;
            }
        }
    }
     
    04 August 2008
    Mike Stone
  • Ich denke, Sie sind am besten hackfisch, wenn Sie die Komposition im Gegensatz zur Vererbung betrachten.

    Sie können auch eine Benutzeroberfläche erstellen, die die gewünschten Mitglieder enthält , lassen Sie Ihre abgeleitete Klasse diese Schnittstelle implementieren und programmieren Sie sie gegen die Schnittstelle.

    04 August 2008
    mrdenny
  • Vollständig ausblenden und markieren, um nicht zu verwenden, einschließlich Intellisense, was meiner Meinung nach die meisten Leser erwarten ...

     [Obsolete("Not applicable in this class.")] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
     
    24 June 2013
    Robert
  • Ich weiß, dass es mehrere Antworten gab, und das ist jetzt ziemlich alt, aber die einfachste Methode, dies zu tun, besteht darin, sie als new private zu deklarieren.

    Betrachten Sie ein Beispiel, an dem ich gerade arbeite, wo ich eine API habe, die jede Methode in einer Drittanbieter-DLL verfügbar macht. Ich muss ihre Methoden nehmen, aber ich möchte eine .Net-Eigenschaft anstelle der Methoden "getThisValue" und "setThisValue" verwenden. Also erstelle ich eine zweite Klasse, übernehme die erste Klasse, erstelle eine Eigenschaft, die die Methoden get und set verwendet, und überschreibe dann die ursprünglichen Methoden get und set als privat. Sie stehen weiterhin allen zur Verfügung, die etwas anderes aufbauen wollen, aber wenn sie nur die Engine verwenden möchten, die ich baue, können sie Eigenschaften anstelle von Methoden verwenden.

    Mit der Doppelklassenmethode werden alle Einschränkungen aufgehoben, die dazu führen, dass die Deklaration new nicht verwendet werden kann, um die Member auszublenden. Sie können override einfach nicht verwenden, wenn die Mitglieder als virtuell markiert 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 verfügbar für beide Klassen, aber nur die Eigenschaft ist in der APIUsageClass-Klasse sichtbar. Die APIClass-Klasse steht weiterhin für Benutzer zur Verfügung, die die ursprüngliche API erweitern oder auf andere Weise verwenden möchten, und die APIUsageClass ist für alle verfügbar, die etwas Einfacheres suchen.

    Letztendlich Ich werde die APIClass intern machen und nur meine geerbte Klasse offenlegen.

    09 December 2010
    Nathan Wheeler
  • Ich habe alle vorgeschlagenen Lösungen getestet, und neue Mitglieder werden nicht wirklich ausgeblendet.

    Aber diese tut TUN:

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

    Aber in code-behide ist es immer noch verfügbar. Fügen Sie auch das veraltete Attribut hinzu.

     [Obsolete("This property is not supported in this class", true)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public new string MyHiddenProperty
    { 
        get { return _myHiddenProperty; }
    }
     
    21 October 2012
    Uwe Keimwolle23
  • 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();
            }
        }
     
    13 November 2017
    acon