Maybe a little tricky, but I wonder why. In System.Linq.Enumerable.cs
of System.Core.dll
we have:
public static int Count<TSource>(this IEnumerable<TSource> source);
In my code I'm doing something evil:
namespace Test
{
public static class Extensions
{
public static int Count<TSource>(this IEnumerable<TSource> source)
{
return -1; //evil code
}
}
//commented temporarily
//public static class CommentedExtensions
//{
// public static int Count<TSource>(this IEnumerable<TSource> source)
// {
// return -2; //another evil code
// }
//}
public static void Main(string[] args)
{
Console.WriteLine(Enumerable.Range(0,10).Count()); // -1, evil code works
Console.Read();
}
}
If I uncomment CommentedExtensions
, I'll get a compile error saying "this call is ambiguous blabla" as expected. But why I didn't get this error at the first time? It's also ambiguous!
EDIT After another test, I found that I won't get compile errors if the extension methods are in different namespaces, even they are completely the same. Why it's allowed? It brings ambiguous call of methods in c#.
EDIT2 I know in fact the two Count
are different in IL. In fact it's calling
Enumerable.Count(Enumerable.Range(0,10))
and my evil extension method is calling:
MyExtension.Count(Enumerable.Range(0,10))
so they are different. But still I think it's a bad smell. Do we have "real" extension methods? which can prevent the evil behavior?