Hiding inherited members

Viewed 29958

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 classes inherit dependency properties which have become vestigial and can be a little confusing when using IntelliSense or using the classes in a visual designer.

These classes are all controls that are written to be compiled for either WPF or Silverlight 2.0. I know about ICustomTypeDescriptor and ICustomPropertyProvider, but I'm pretty certain those can't be used in Silverlight.

It's not as much a functional issue as a usability issue. What should I do?

Update

Some of the properties that I would really like to hide come from ancestors that are not my own and because of a specific tool I'm designing for, I can't do member hiding with the new operator. (I know, it's ridiculous)

9 Answers

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.

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.

One potential thing you can do is contain the object rather than extend from the other class. This will give you the most flexibility in terms of exposing what you want to expose, but if you absolutely need the object to be of that type it is not the ideal solution (however you could expose the object from a getter).

Thus:

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

Becomes:

public class MyClass
{
    private BaseClass baseClass;

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

Or:

public class MyClass
{
    private BaseClass baseClass;

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

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.

While clearly stated above that it is not possible in C# to change the access modifiers on inherited methods and properties, I overcame this issue through a sort of "fake inheritance" using implicit casting.

Example:

public class A
{
      int var1;
      int var2;

      public A(int var1, int var2)
      {
            this.var1 = var1;
            this.var2 = var2;
      }
      public void Method1(int i)
      {
            var1 = i;
      }
      public int Method2()
      {
            return var1+var2;
      }
}

Now lets say you want a class B to inherit from class A, but want to change some accessibility or even change Method1 entirely

public class B
{
      private A parent;

      public B(int var1, int var2)
      {
            parent = new A(var1, var2);
      } 

      int var1 
      {
            get {return this.parent.var1;}
      }
      int var2 
      {
            get {return this.parent.var2;}
            set {this.parent.var2 = value;}
      }

      public Method1(int i)
      {
            this.parent.Method1(i*i);
      }
      private Method2()
      {
            this.parent.Method2();
      }


      public static implicit operator A(B b)
      {
            return b.parent;
      }
}

By including the implicit cast at the end, it allows us to treat B objects as As when we need to. It can also be useful to define an implicit cast from A->B.

The biggest flaw to this approach is that you need to re-write every method/property that you intend to "inherit". There's probably even more flaws to this approach, but I like to use it as a sort of "fake inheritance".

Note:

While this allows for changing the accessibility of public properties, it doesn't solve the issue of making protected properties public.

You can use an interface

    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();
        }
    }
Related