Search code examples
c#genericsmethodsintellisenseoverloading

Visual Studio Intellisense not showing methods on generic overload


Given the following two interfaces (these are small examples, not my actual implementation):

public interface IAssertion<T> {
     IAssertion<T> IsNotNull();
     IAssertion<T> Evaluate(Predicate<T> predicate)
}

public interface IStringAssertion : IAssertion<string> {
     IStringAssertion IsNotNullOrEmpty();
}

and a static factory that will return the appropriate interface, for example:

public static class Require {
     public static IAssertion<T> That<T>(T value) {
          ...
     }

     public static IStringAssertion That(string value) {
          ...
     }
}

I should be able to do the following:

public void TestMethod(SomeClass a, string b) {
    Require.That(a).IsNotNull();
    Require.That(b).IsNotNullOrEmpty().Evaluate(SomeMethodThatAcceptsString);
}

This code compiles and will actually run. I can even set up tests that pass, such as:

Assert.IsInstanceOf<IStringAssertion>(Require.That(string.Empty));
Assert.IsNotInstanceOf<IStringAssertion>(Require.That(new object());

The problem I am running into and the whole point of this question, is that Visual Studio 2005 intellisense is not resolving the differences between the two.

When I type Require.That("..."). I should expect to see a list of

Evaluate(Predicate predicate)
IsNull()
IsNotNullOrEmpty()

but instead I see nothing.

I would really like to keep the same method name for the overloads. I want to keep the generic overload because of the predicate in the Evaluate method of the IAssertion interface.

Also, I know I can do something close to this using extension methods, but that is not an option because I still want to support .Net 2.0 and would like to keep the fluent api.

Updated:

There have been some good answers that involve third party add-ons to Visual Studio. Unfortunately I am not in a position to either install or purchase add-on tools for Visual Studio due to the corporate red tape that I am developing under. (I hate politics!)

I am looking for a code only option that will work in both Visual Studio 2005 and Visual Studio 2008.

Updated:

This works in Visual Studio 2008. Thank you, Luke. That only leaves Visual Studio 2005.


Solution

  • I believe this is because Intellisense sees the item with the same name as a Generic Type and then doesn't bother to look for the intellisense properties until you give it a type. For example, if you mouse over the "Require.That(string)" Visual Studios will report it as an IAssertion, instead of an IStringAssertion.

    Anyway, you could just rename the "That" for your IStringAssertion to "ThatString". I.e.

    public static class Require
    {
    
        public static IStringAssertion ThatString(string value)
        {
            return null;
        }
    
        public static IAssertion<T> That<T>(T value)
        {
            return null;
        }
    
    }
    
    public class RAR
    {
        public void TestMethod(StringComparer a, string b)
        {
            Require.That<StringComparer>(a).IsNotNull();
            Require.ThatString(b).IsNotNullOrEmpty();
        }
    }
    

    Probably not ideal, but I don't believe there's any way around it on the code front apart from using different method names.