
Visual studio bug: Generic extension method doesn't show up in IntelliSense
I just reported a bug on the Microsoft Connect site about a quirk in the C# IntelliSense feature regarding generic extension methods.
The problem is actually as follows. Let's define a rather awkward generic extension method:
static class IntelliSenseBug_MethodDoesntShowUp
{
public static void Method<TCollection, TElement>(
this TCollection collection, TElement element)
where TCollection : IEnumerable<TElement>
{
}
}
The defined extension method has a generic type constrain that states that the TCollection should be a generic IEnumerable interface that contains elements of type TElement. We can use this extension method with like so:
static void Test()
{
Collection<int> c = new Collection<int>();
c.Method(1);
}
This all compiles fine, but when typing Test() method's code, you'll notice that after typing c + dot the list of possible operations does not contain our defined 'Method'. The C# compiler is smart enough by using type inference that the passed element is in fact an Int32 and that therefore TElement must be of type Int32 and therefore TCollection must be of type IEnumerable<Int32>. At last the compiler finds out that Collection<int> implements IEnumerable<int> and so it all fits together nicely. Unfortunately IntelliSense isn't as smart as the C# compiler. That's a bummer.
B.t.w. You can read my bug report here.
Update 2008-09-09:
This bug has been fixed in Visual Studio 2008 SP1!
- .NET General, C#, LINQ, Visual Studio - two comments / No trackbacks - § ¶
Ah, yes, that is a bug (I just tried it out).
However, if you know that TCollection is an IEnumerable<T>, you could always just define it like:
public static void Method<T>(
this IEnumerable<T> collection, TElement element)
{
}
Then Intellisense picks it up just fine :)
Matt (URL) - 22 06 08 - 17:36
Thank for comments Matt,
Your suggestion indeed works on the supplied example. But now let's consider the following example:
class MyWrapper { }
public static void Method(
this MyWrapper wrapCol, TElement element)
where TCollection : IEnumerable
{ }
Rewriting the method the way you did in your example doesn't give the same method:
public static void Method2(
this MyWrapper wrapCol, T element)
{ }
You'll notice the difference when you try to compile the following code:
MyWrapper wrapper =
new MyWrapper();
wrapper.Method(1);
wrapper.Method2(1); // CS1061
The call to Method2 will not compile by the lack of Covariance and contra variance support in .NET for Generics.
Steven (URL) - 23 06 08 - 10:21