Should intellisense do what you want, or do what's correct?

Ok, that could be a terribly misleading title, but hopefully some explanation will help clarify things.  I just got a bug assigned to me complaining about the following behavior.  Say you have the following:

Yes master!

Looks good right?  Well, not quite.  Technically, the list of valid things after an enum name plus a dot are all the other things we would have found while resolving the static members in the inheritance chain.  So we could have shown you:

        public static string Format(Type enumType, object value, string format);

        public static string GetName(Type enumType, object value);

        public static string[] GetNames(Type enumType);

        public static Type GetUnderlyingType(Type enumType);

        public static Array GetValues(Type enumType);

        public static bool IsDefined(Type enumType, object value);

        public static object Parse(Type enumType, string value);


In this case we didn't because (in one of the extremely rare cases where we filter out elements of a list) we felt that it would actually be a detriment to show you things that would be legal to use in that circumstance.  We normally have a policy for showing everything valid because we believe that intellisense shouldn't interfere with typing.  I.e. you should be able to type in whatever you wanted to get verbatim and not have the intellisense system screw you up.  Of course, we already violate this when you hit <dot> and try to access a member you haven't defined yet.  We err in that case with the presumption that accessing a pre-existing element is far more likely than accessing one you're about to create.  Of course, methodologies like TDD have forced us to rethink this and realize that there is indeed a class of users for which this behavior can be undesirable in a large percentage of cases. 

In this specific case the reasoning was two part.  First, if you're accessing a specific enum type (like color) your almost certainly want to access one of its elements (if you think this assumption is wrong let me know!).  Second, the elements we are masking are accessible if you type out “Enum<dot>”, so it's not horrible to remove them since they are accessible.

We often times get a suggestion that when a user types “throw new<space>” we should automatically pop up the list prefiltered to only things that are exceptions.  The problem with that is that really after a “throw” any expression is legal as long as it evaluates to a type that derives from exception.  While rare, it happens that people do interesting things like throwing preexisting exceptions that they've retreived from some storage or have created in novel ways.  Unlike the Enum case above, there is no way to type the expression without having our filtering interfere.

I mentioned that I wasn't sure if the title of this post was really appropriate.  It implies an either/or relationship between the two ideas.  It's quite possible that there are those out there (like the person who opened the bug) that what they want is for intellisense not to try to guess what you're doing and filter but to always show what it knows to be valid to the best of it's abilities.  However, I do believe that there are a lot of people out there who would like intellisense to be smarter, and up to know have not realized why it is we don't do certain “smart filterings” based on what you've typed.  This is an area I really want to address with the next version and I'd like to do so in a way that benefits both those who want the development advantages smart filtering could provide and does not hinder those who don't want intellisense second guessing them and making their life harder.

Have you felt at times “why can't intellisense be smarter right now?” or “why is it showing my so much stuff I don't care about?” then let us now so that when we work on a system that tries to be better than the current one we can make sure we're addressing the cases that you've brought up.

Edit: System.Enum and System.Exception have been discussed as areas for smarter filtering of completion lists.  Are there other areas where you see this being helpful.  It should be noted that for VS2005 we've implemented filtering of completion lists for attribute declarations down to types that derive from System.Attribute.  For catch blocks we filter down to types that derive from Exception; and we're thinking about introducing a filter down to types that derive from Delegate when you're declaring an event's return type.