Delta Engine Blog

AI, Robotics, multiplatform game development and Strict programming language

How to keep the Intellisense info box short and tidy

If you ever have wondered why you need all these Object class method in your class intellisense list, this is the right article for you. I recently wrote an Assert class for our own unit testing system (as reported yesterday we were pretty unhappy with TestDriven.net+xunit in our engine). Even though I have only written 10 methods in the Assert class, which I think are the most essential ones for unit testing, whenever I write Assert. Intellisense pops up with 15 Items instead of 10. In my case (statically accessing Assert) the following 5 Items were displayed without my consens:

  • The Contains method appears 2 times because one is using strings, the other overload is using generics
  • object.Equals appears because every class is derived from object!
  • Same for object.ReferenceEquals
  • The sub class Tests appears to, but I only need it for unit testing (but it needs to be public for xunit)
  • And finally there is a delegate ThrowsDelegate, which is needed for the Throws method.

Additionally if you access a class via an instance (not statically) you will get the following object methods displayed in your intellisense too:

  • Equals (there is one static method with 2 arguments and a non static one with 1 argument)
  • GetType
  • GetHashCode
  • And finally ToString

 

I cannot remember the last time I really needed those object methods in any classes intellisense. Luckily there is an easy solution to fix this, but you need to be aware that it does not work in every situation. But as you can see I managed to reduce my Assert class intellisense list down to the 10 items I really wanted:

 

Basically you just add the following attribute to any method, sub class or property that you do not want to appear in the intellisense list:

[EditorBrowsable(EditorBrowsableState.Never)]

This works fine and dandy with your own methods (like in my example the ThrowsDelegate and the Tests sub class, but what about those nasty object methods? Well, static methods you can just re-implement with the new keyword (overwriting the original methods) and just specify the EditorBrowsable attribute there:

#region Hide object.Equals and object.ReferenceEquals
/// 
/// Equals
/// 
[EditorBrowsable(EditorBrowsableState.Never)]
public new static bool Equals(object objA, object objB)
{
	return object.Equals(objA, objB);
} // Equals(objA, objB)

/// 
/// Reference equals
/// 
[EditorBrowsable(EditorBrowsableState.Never)]
public new static bool ReferenceEquals(object objA, object objB)
{
	return object.ReferenceEquals(objA, objB);
} // ReferenceEquals(objA, objB)
#endregion

For the non-static methods we can even use a simpler trick by deriving your class from the following IHideObjectMembers interface, which already adds the required attributes to the 4 annoying object methods.

/// 
/// Helper interface used to hide the base  members from
/// your classes to make intellisense much cleaner. Note: This ONLY works
/// from other assemblies AND you MUST NOT have the project using this
/// interface in your solution (else VS will still show them).
/// 
[EditorBrowsable(EditorBrowsableState.Never)]
public interface IHideObjectMembers
{
	[EditorBrowsable(EditorBrowsableState.Never)]
	Type GetType();

	[EditorBrowsable(EditorBrowsableState.Never)]
	int GetHashCode();

	[EditorBrowsable(EditorBrowsableState.Never)]
	string ToString();

	[EditorBrowsable(EditorBrowsableState.Never)]
	bool Equals(object obj);
} // interface IHideObjectMembers

One final thing I had to do to get rid of my two Contains methods was to rewrite the string one to a generic one, so it appears together with the other generic one (using lists) in the Intellisense list, but that was no biggy.


When you try this out you might wonder why the hell it is not working for you and sadly the answer is: Yes, it does not work all of the time. As already mentioned in the IHideObjectMembers implementation the hiding only works if you DO NOT HAVE the assembly from the class you are intellisensing in your solution. You need to reference it as an dll (a local file or from the GAC). Even then you might want to create a new solution for testing this out. The strange thing is that after a while VS seems to learn and will use your reduced intellisense even if you have the project in the solution, but I have no idea why this sometimes works (when writing this blog entry it almost always worked inside my Assert assembly even). Anyway, it is still a very useful trick IMO.