How to call global static method from class static method in C#?

67 views Asked by At

The following program compiles et executes just fine in recent versions of C#, where a Main function is not necessary:

Module2.SayHelloDouble();

static class Module1
{
    public static void SayHello()
        => Console.WriteLine("Hello!");
}

static class Module2
{
    public static void SayHelloDouble()
    {
        Module1.SayHello();
        Module1.SayHello();
    }
}

However, if I make the SayHello method "global static", the program does not compile anymore (verified with C# 12 / NET 8).

cannot access global static method from class method

Is there a way to access a "global scope static method" from inside a class method ? Or is that simply impossible ?

2

There are 2 answers

0
Guru Stron On BEST ANSWER

However, if I make the SayHello method "global static"

The thing is that you are not making it global in any way, you are making it a local function (basically vice versa from what you have expected) for Program.$Main method which will be generated for top-level statement:

Module2.SayHelloDouble();
static void SayHello() => Console.WriteLine("Hello!");

Top-level statements is a feature introduced with C# 9 which allows to skip some boilerplate code for Main method declaration and make compiler it do for you.

Basically the following:

Module2.SayHelloDouble();

static void SayHello() => Console.WriteLine("Hello!");

static class Module2
{
    public static void SayHelloDouble()
    {
        // no-op
    }
}

Is turned by compiler to something like the following (a bit simplified, full decompilation @sharplab.io):

[CompilerGenerated]
internal class Program
{
    private static void <Main>$(string[] args)
    {
        Module2.SayHelloDouble();
        // your local method, accessible in the generated Main method
        static void SayHello() => Console.WriteLine("Hello!");
    }

    [CompilerGenerated]
    internal static void <<Main>$>g__SayHello|0_0()
    {
        Console.WriteLine("Hello!");
    }
}

internal static class Module2
{
    public static void SayHelloDouble()
    {
    }
}
1
Peter Csala On

If you want to make it available inside Module2 & inside the top-level statement
then you can do the following trick:

SayHello();
Module2.SayHelloDouble();

static class Module2
{
    public static void SayHelloDouble()
    {
        Program.SayHello();
        Program.SayHello();
    }
}

public static partial class Program 
{ 
    public static void SayHello() => Console.WriteLine("Hello!");
}
  • Define a partial static Program class and move there the SayHello
  • Don't forget to add public accessor for the SayHello method
  • Call SayHello through the Program class inside the SayHelloDouble method

UPDATE #1

With using static Program; you can eliminate the need to prepend the SayHello calls with Program. inside the SayHelloDouble. But the solution gets uglier and uglier...

using static Program;

SayHello();
Module2.SayHelloDouble();

static class Module2
{
    public static void SayHelloDouble()
    {
        SayHello();
        SayHello();
    }
}

public static partial class Program 
{ 
    public static void SayHello() => Console.WriteLine("Hello!");
}