Методы расширения и проверка во время компиляции

Может быть, немного сложно, но мне интересно, почему. В 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))

, поэтому они разные. Но все же я думаю, что это неприятный запах. Есть ли у нас «настоящие» методы расширения? что может предотвратить злое поведение?

5
задан Cheng Chen 13 October 2010 в 06:24
поделиться