Может быть немного сложно, но мне интересно, почему. В System.Linq.Enumerable.cs
из System.Core.dll
имеем:
public static int Count<TSource>(this IEnumerable<TSource> source);
В моем коде я делаю что-то злое:
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();
}
}
Если я раскомментирую CommentedExtensions
, я получу ошибку компиляции, говоря, что «этот вызов неоднозначный блабла», как и ожидалось. Но почему я не получил эту ошибку в первый раз? Это также неоднозначно!
EDIT После другого теста я обнаружил, что не получу ошибок компиляции, если методы расширения находятся в разных пространствах имен, даже если они абсолютно одинаковы. Почему это разрешено? Это приносит неоднозначный вызов методов в c #.
EDIT2 Я знаю, что на самом деле два Count
различны в IL. На самом деле это звонит
Enumerable.Count(Enumerable.Range(0,10))
и мой злой метод расширения вызывает:
MyExtension.Count(Enumerable.Range(0,10))
поэтому они разные. Но все же я думаю, что это плохой запах. Есть ли у нас "настоящие" методы расширения? что может предотвратить злое поведение?