20

Background:

I had a static class, but the static methods weren't extension methods. I decided to refactor the methods into extension methods and didn't expect any code to break since extension methods can be called like static methods. However, code did break when static import was used for the static class holding the extension methods.

Example:

I have a static class with an extension method and a static method:

namespace UsingStaticExtensionTest.Extensions
{
    static class ExtensionClass
    {
        internal static void Test1(this Program pg)
        {
            System.Console.WriteLine("OK");
        }

        internal static void Test2(Program pg)
        {
            System.Console.WriteLine("OK");
        }

    }
}

When I use the following using directive, everything in the test program works fine:

using UsingStaticExtensionTest.Extensions;
namespace UsingStaticExtensionTest

    {
        class Program
        {
            static void Main(string[] args)
            {
                var p = new Program();
                ExtensionClass.Test1(p); // OK
                p.Test1(); // OK
                ExtensionClass.Test2(p); // OK
            }
        }
    }

But when I use the static import using directive to identify just the class with the extension method, I can't call the extension method as a static method:

using static UsingStaticExtensionTest.Extensions.ExtensionClass;
    class Program
    {
        static void Main(string[] args)
        {
            var p = new Program();
            //Test1(p); // Error: The name Test1 does not exist in the current context
            p.Test1(); // OK
            Test2(p); // OK **I can still call the static method**
        }
    }
}

Question: Why can't I call an extension method as a static method when using a static import?

Frank Tan
  • 4,234
  • 2
  • 19
  • 29
astidham2003
  • 966
  • 1
  • 11
  • 33
  • 1
    Probably a quirk of the syntax handling here, the syntax for an extension method requires an expression to invoke the extension method on. In other words, inside a class you can't simply do `ExtensionMethod();`; and imply `this.`. Looks like this syntax enforcement for an extension method trumps the static import. – Lasse V. Karlsen Aug 16 '16 at 21:40

1 Answers1

15

Because of language design:

Using static makes extension methods declared in the specified type available for extension method lookup. However, the names of the extension methods are not imported into scope for unqualified reference in code.

using Directive

Carl Walsh
  • 6,100
  • 2
  • 46
  • 50
Hamlet Hakobyan
  • 32,965
  • 6
  • 52
  • 68
  • 6
    Nice answer. Anyone knows the reasoning for this? It seems counter intuitive in principle, but I may be missing something. – Isaac Llopis Aug 25 '17 at 16:16
  • @IsaacLlopis It can be discriminating (for extension [static] methods) to do not import them for unqualified reference but this can be counterintuitive much more since there can be lost given meaning. Like `void Substract(this Collection, Collection)`. If qualified it is not obvious which of the 2 will be _minuend_ while Collection.Substract(Collection) is obvious, I hope. Nobody would use unqualified approach in the end. – Yarl Nov 04 '20 at 19:44