69

I want to hide public methods from the IntelliSense member list. I have created an attribute that, when applied to a method, will cause the method to be called when its object is constructed. I've done this to better support partial classes. The problem is that in some environments (such as Silverlight), reflection cannot access private members, even those of child classes. This is a problem since all of the work is done in a base class. I have to make these methods public, but I want them to be hidden from IntelliSense, similar to how the Obsolete attribute works. Frankly, because I am anal about object encapsulation. I've tried different things, but nothing has actually worked. The method still shows up in the member drop-down.

How do I keep public methods from showing up in IntelliSense when I don't want them to be called by clients? How's that for a real question, Philistines! This can also apply to MEF properties that have to be public though sometimes you want to hide them from clients.

Update: I have matured as a developer since I posted this question. Why I cared so much about hiding interface is beyond me.

Pang
  • 9,564
  • 146
  • 81
  • 122
Jordan
  • 9,642
  • 10
  • 71
  • 141
  • 3
    Don't make them public if you don't want them to be accessed/used. – Oded Jan 31 '12 at 20:08
  • So instead of just adding calls to methods in the constructor of an object, you are adding attributes and calling them via reflection? As far as your comment about "better support partial classes", isn't that what partial methods are for? – cadrell0 Jan 31 '12 at 20:15
  • 2
    Explicit interface implementation might be an alternative approach to consider. The methods then are not part of the public API of the class, but only visible via the interface. – Anthony Pegram Jan 31 '12 at 20:16
  • @AnthonyPegram, I tried this, but it resulted a similar reflection access problem. It seems that reflection in certain scenarios can only access public members of other classes (even child classes). – Jordan Jan 31 '12 at 20:22
  • @cadrell0, Partial methods don't multiplex do they? Also, I've done time tests between my attribute and explicit calling from the main constructor and the difference is negligible. This method makes my code a whole lot cleaner when dealing with code generation. – Jordan Jan 31 '12 at 20:24
  • @Jordan Sorry, I was assuming two parts to a class. If you have more than one, you could just do it with a private event. – cadrell0 Jan 31 '12 at 20:31
  • @cadrell0, But something would have to hook up the event. I was wanting, for reasons unknown, the primary class to be ignorant about the partial classes. I don't think encapsulation should be taken to that level. I was suffering from software OCD or something. Been coding too much today. I'm straightened out now. – Jordan Jan 31 '12 at 20:38
  • 2
    @Jordan I am fortunate enough to have coworkers that smack me in the head when I start over engineering things. – cadrell0 Jan 31 '12 at 20:51

3 Answers3

156

Using the EditorBrowsable attribute like so will cause a method not to be shown in IntelliSense:

[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public void MyMethod()
{
}
Pang
  • 9,564
  • 146
  • 81
  • 122
Adi Lester
  • 24,731
  • 12
  • 95
  • 110
  • 9
    Yeah, I tried this. It doesn't work. The method still shows in the member list. – Jordan Jan 31 '12 at 20:28
  • 22
    @Jordan I tried it myself just now and it doesn't show the method when I'm referencing the library's dll. However, it does show if the project is in the same solution and I'm referencing the project. – Adi Lester Jan 31 '12 at 20:31
  • 11
    Yes, that's the expected behavior. It's not intended to filter items from *you* as you write the code! – Cody Gray - on strike Jan 31 '12 at 20:33
  • 3
    Indeed. I'm breaking OOP rules for the sake of cleaner code. I'm suffering from software OCD or something. – Jordan Jan 31 '12 at 20:33
  • 3
    It used to work in VB.Net and older Visual Studio versions but then they changed it and incorporated the incorrect behavior of C#, where it is not respected anymore if the project is in the same solution. And there is not even an option to choose the behavior. :-( – Christoph Nov 09 '18 at 11:02
22

You are looking for EditorBrowsableAttribute

The following sample demonstrates how to hide a property of a class from IntelliSense by setting the appropriate value for the EditorBrowsableAttribute attribute. Build Class1 in its own assembly.

In Visual Studio, create a new Windows Application solution, and add a reference to the assembly which contains Class1. In the Form1 constructor, declare an instance of Class1, type the name of the instance, and press the period key to activate the IntelliSense drop-down list of Class1 members. The Age property does not appear in the drop-down list.

using System;
using System.ComponentModel;

namespace EditorBrowsableDemo
{
    public class Class1
    {
        public Class1()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        int ageval;

        [EditorBrowsable(EditorBrowsableState.Never)]
        public int Age
        {
            get { return ageval; }
            set
            {
                if (!ageval.Equals(value))
                {
                    ageval = value;
                }
            }
        }
    }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
SimSimY
  • 3,616
  • 2
  • 30
  • 35
-4

To expand on my comment about partial methods. Try something like this

Foo.part1.cs

partial class Foo
{
    public Foo()
    {
        Initialize();
    }

    partial void Initialize();
}

Foo.part2.cs

partial class Foo
{
    partial void Initialize()
    {
         InitializePart1();
         InitializePart2();
         InitializePart3();
    }

    private void InitializePart1()
    {
        //logic goes here
    }

    private void InitializePart2()
    {
        //logic goes here
    }

    private void InitializePart3()
    {
        //logic goes here
    }
}
cadrell0
  • 17,109
  • 5
  • 51
  • 69
  • This is ultimately what I did. *sigh* – Jordan Jan 31 '12 at 20:38
  • Well, not exactly. I just used private methods in the partial classes that I called from the primary class. I have multiple partial classes, I'm crazy. Need help. *sigh* – Jordan Jan 31 '12 at 20:39