0

Sometimes it becomes necessary to write some helper that is applicable only in the code of some method. I've tried to write extension method locally (as in static local functions), but the program does not compile.

The minimal repeatable example:

public static class Program {
    public static void Main() {
        static string ToLowerFirst(this string str)=>!string.IsNullOrEmpty(str) && char.IsUpper(str[0])?str.Length == 1 ? char.ToLower(str[0]).ToString() : char.ToLower(str[0]) + str[1..]:str;
      
        string s = "CamelCase";
        Console.WriteLine(s.ToLowerFirst());
    }
}

Error text: [CS1106] Extension methods must be defined in a non generic static class. Extension methods must be defined as static methods in a non-generic static class.

I did something wrong?

What the actual class of method with full name Program.<Main>g__ToLowerFirst|0_0?

Reverin
  • 49
  • 8
  • 3
    The simple answer seems to be that local extension methods are not implemented, and [features are unimplemented by default](https://stackoverflow.com/a/8673015). As to why it doesn't work automatically, according to the [docs](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods#general-guidelines) ***Extension methods are brought into scope at the namespace level*** but this doesn't seem possible for a local functions which lives only within given members. – dbc Jul 18 '23 at 20:46
  • Including the actual error message would help a lot. I realize you are probably not a native English speaker, but _"The error describes that extension method should be declared in not generic static class. But that's the way it is probably."_ is pretty hard to decipher. You can segregate your extension methods with Namespaces. The method is only available if you add `using NamespaceWithSpecialExtensionMethod;` in your source file – Flydog57 Jul 18 '23 at 20:46
  • If you make `ToLowerFirst()` be a static function in the `Program` class, rather than a static local function inside `Main()`, then your code compiles,see https://dotnetfiddle.net/M5sVRA. Does that answer your question? – dbc Jul 18 '23 at 20:49
  • @dbc, no, I was thinking about specific actions for a method. In the proposed case, the method will be visible to the class level. Well, then just to remove the word this in function definition. – Reverin Jul 18 '23 at 21:14
  • @Flydog, the actual error message is [CS1106](https://learn.microsoft.com/en-us/dotnet/csharp/misc/cs1106?f1url=%3FappId%3Droslyn%26k%3Dk(CS1106)) – Reverin Jul 18 '23 at 21:14
  • @Reverin - right. Your static function can be local, or an extension method at the class level. Just not both. Keeping it local, removing the `this` and doing `ToLowerFirst(s)` also works. – dbc Jul 18 '23 at 21:21
  • If you have an extension method `m(this string str) { ... }` defined in `static class Program`, then a call **`str.m()`** actually executes as if you wrote **`Program.m(str)`**. That whole mechanism breaks if you try to make `m` a local function inside some other method. It just is not supported by the compiler. – Peter B Jul 18 '23 at 21:32
  • If you're writing a library you should consider making the containing static class `internal`. – Aluan Haddad Jul 19 '23 at 23:03

1 Answers1

1

It's quite simple, extension methods can't be local.

The help message could be a little more helpful, because your method is defined in a non-generic static class, but crucially it's also inside of another method and that's your dealbreaker.

I suspect that's because the error message has existed a lot longer than local functions have.


If you move your method outside of main(), you should be okay but it won't be local anymore.

ScottishTapWater
  • 3,656
  • 4
  • 38
  • 81