Может быть, немного сложно, но мне интересно, почему. В 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
, как и ожидалось, я получу сообщение об ошибке компиляции, в котором говорится, что "этот вызов неоднозначный, blabla". Но почему я не получил эту ошибку в первый раз? Это тоже неоднозначно!
РЕДАКТИРОВАТЬ После еще одного теста я обнаружил, что не получу ошибок компиляции, если методы расширения находятся в разных пространствах имен, даже если они полностью одинаковы. Почему это разрешено? Это приводит к неоднозначному вызову методов в C #.
EDIT2 Я знаю, что два Count
различны в IL. Фактически он вызывает
Enumerable.Count(Enumerable.Range(0,10))
, а мой злой метод расширения вызывает:
MyExtension.Count(Enumerable.Range(0,10))
, поэтому они разные. Но все же я думаю, что это неприятный запах. Есть ли у нас «настоящие» методы расширения? что может предотвратить злое поведение?