Extension method priority

前端 未结 2 1206
再見小時候
再見小時候 2020-12-11 07:10

I read from https://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx that extension methods with same name and signature as existing ones on the base type are never ca

2条回答
  •  [愿得一人]
    2020-12-11 07:57

    Here is a longer example with five possible Where<> methods:

    using System;
    using System.Collections.Generic;
    using System.Linq; // **OUTSIDE**
    
    namespace Me.MyName
    {
      using System.MySuperLinq; // **INSIDE**
    
      static class Test
      {
        static void Main()
        {
          (new[] { "Hans", "Birgit" }).Where(x => x == "Hans");
        }
      }
    }
    
    namespace System.MySuperLinq
    {
      static class Extensions
      {
        public static IEnumerable Where(this IEnumerable source, Func predicate)
        {
          Console.WriteLine("My own MySuperLinq method");
          return null; // will fix one day
        }
      }
    }
    
    namespace Me.MyName
    {
      static class Extensions
      {
        public static IEnumerable Where(this IEnumerable source, Func predicate)
        {
          Console.WriteLine("My own MyName method");
          return null; // will fix one day
        }
      }
    }
    
    namespace Me
    {
      static class Extensions
      {
        public static IEnumerable Where(this IEnumerable source, Func predicate)
        {
          Console.WriteLine("My own Me method");
          return null; // will fix one day
        }
      }
    }
    
    // this is not inside any namespace declaration
    static class Extensions
    {
      public static IEnumerable Where(this IEnumerable source, Func predicate)
      {
        Console.WriteLine("My own global-namespace method");
        return null; // will fix one day
      }
    }
    

    Try successively removing which ever method is preferred, to see the "priority" the C# compiler uses.

    • The C# compiler will first search for static classes inside Me.MyName namespace since that is the "current" namespace.
    • It will then search in System.MySuperLinq because that using is inside.
    • It will then go out one level and search in Me namespace
    • It will then search in the global (null) namespace.
    • Finally, it will serach System, System.Collections.Generic, and System.Linq.

    If two or more equally relevant methods are found at one "level" (bullets above), that is a compile-time ambiguity (will not compile).

提交回复
热议问题