Hiding inherited members

前端 未结 9 1888
北海茫月
北海茫月 2020-12-03 09:52

I\'m looking for some way to effectively hide inherited members. I have a library of classes which inherit from common base classes. Some of the more recent descendant clas

相关标签:
9条回答
  • 2020-12-03 10:01

    I tested all of the proposed solutions and they do not really hide new members.

    But this one DOES:

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

    But in code-behide it's still accessible, so add as well Obsolete Attribute

    [Obsolete("This property is not supported in this class", true)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public new string MyHiddenProperty
    { 
        get { return _myHiddenProperty; }
    }
    
    0 讨论(0)
  • 2020-12-03 10:03

    I think you're best least hackish way is to consider composition as opposed to inheritance.

    Or, you could create an interface that has the members you want, have your derived class implement that interface, and program against the interface.

    0 讨论(0)
  • 2020-12-03 10:08

    While you cannot prevent usage of those inherited members to my knowledge, you should be able to hide them from IntelliSense using the EditorBrowsableAttribute:

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

    Edit: Just saw this in the documentation comments, which makes it kinda useless for this purpose:

    There is a prominent note that states that this attribute "does not suppress members from a class in the same assembly". That is true but not complete. Actually, the attribute does not suppress members from a class in the same solution.

    0 讨论(0)
  • 2020-12-03 10:10

    I know there's been several answers to this, and it's quite old now, but the simplest method to do this is just declare them as new private.

    Consider an example I am currently working on, where I have an API that makes available every method in a 3rd party DLL. I have to take their methods, but I want to use a .Net property, instead of a "getThisValue" and "setThisValue" method. So, I build a second class, inherit the first, make a property that uses the get and set methods, and then override the original get and set methods as private. They're still available to anyone wanting to build something different on them, but if they just want to use the engine I'm building, then they'll be able to use properties instead of methods.

    Using the double class method gets rid of any restrictions on being unable to use the new declaration to hide the members. You simply can't use override if the members are marked as virtual.

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

    Now valueEnum is available to both classes, but only the property is visible in the APIUsageClass class. The APIClass class is still available for people who want to extend the original API or use it in a different way, and the APIUsageClass is available for those who want something more simple.

    Ultimately, what I'll be doing is making the APIClass internal, and only expose my inherited class.

    0 讨论(0)
  • 2020-12-03 10:16

    To fully hide and mark not to use, including intellisense which I believe is what most readers expect ...

    [Obsolete("Not applicable in this class.")] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    
    0 讨论(0)
  • 2020-12-03 10:19

    Override them like Michael Suggests above and to prevent folks from using the overridden (sp?) methods, mark them as obsolete:

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

    If the second parm is set to true, a compiler error will be generated if anyone tries to call that method and the string in the first parm is the message. If parm2 is false only a compiler warning will be generated.

    0 讨论(0)
提交回复
热议问题