Instrucciones de nivel superior: programas sin métodos Main

No es necesario incluir explícitamente un método Main en un proyecto de aplicación de consola. En su lugar, puede usar la característica de instrucciones de nivel superior para minimizar el código que tiene que escribir.

Las instrucciones de nivel superior permiten escribir código ejecutable directamente en la raíz de un archivo, lo que elimina la necesidad de encapsular el código en una clase o método. Esto significa que puede crear programas sin la ceremonia de una clase Program y un método Main. En este caso, el compilador genera una clase Program con un método de punto de entrada para la aplicación. El nombre de este método no es en realidad Main, es un detalle de implementación al que el código no puede hacer referencia directamente.

Aquí se muestra un archivo Program.cs que es un programa de C# completo en C# 10:

Console.WriteLine("Hello World!");

Las instrucciones de nivel superior permiten escribir programas sencillos para utilidades pequeñas, como Azure Functions y Acciones de GitHub. También facilitan a los nuevos programadores de C# empezar a aprender y escribir código.

En las secciones siguientes se explican las reglas de lo que puede y no puede hacer con las instrucciones de nivel superior.

Solo un archivo de nivel superior

Una aplicación solo debe tener un punto de entrada. Un proyecto solo puede tener un archivo con instrucciones de nivel superior. Al colocar instrucciones de nivel superior en más de un archivo de un proyecto, se produce el error del compilador siguiente:

CS8802 Solo una unidad de compilación puede tener instrucciones de nivel superior.

Un proyecto puede tener cualquier número de archivos de código fuente adicionales que no tengan instrucciones de nivel superior.

Ningún otro punto de entrada

Puede escribir un método Main de forma explícita, pero no puede funcionar como punto de entrada. El compilador emite la advertencia siguiente:

CS7022 El punto de entrada del programa es código global: se ignora el punto de entrada "Main()".

En un proyecto con instrucciones de nivel superior, no se puede usar la opción del compilador -main para seleccionar el punto de entrada, incluso si el proyecto tiene uno o varios métodos Main.

Directivas using

Si incluye directivas using, deben aparecer en primer lugar en el archivo, como en este ejemplo:

using System.Text;

StringBuilder builder = new();
builder.AppendLine("Hello");
builder.AppendLine("World!");

Console.WriteLine(builder.ToString());

Espacio de nombres global

Las instrucciones de nivel superior están implícitamente en el espacio de nombres global.

Espacios de nombres y definiciones de tipos

Un archivo con instrucciones de nivel superior también puede contener espacios de nombres y definiciones de tipos, pero deben aparecer después de las instrucciones de nivel superior. Por ejemplo:

MyClass.TestMethod();
MyNamespace.MyClass.MyMethod();

public class MyClass
{
    public static void TestMethod()
    {
        Console.WriteLine("Hello World!");
    }
}

namespace MyNamespace
{
    class MyClass
    {
        public static void MyMethod()
        {
            Console.WriteLine("Hello World from MyNamespace.MyClass.MyMethod!");
        }
    }
}

args

Las instrucciones de nivel superior pueden hacer referencia a la variable args para acceder a los argumentos de línea de comandos que se hayan escrito. La variable args nunca es NULL, pero su valor Length es cero si no se han proporcionado argumentos de línea de comandos. Por ejemplo:

if (args.Length > 0)
{
    foreach (var arg in args)
    {
        Console.WriteLine($"Argument={arg}");
    }
}
else
{
    Console.WriteLine("No arguments");
}

await

Puede llamar a un método asincrónico mediante el uso await. Por ejemplo:

Console.Write("Hello ");
await Task.Delay(5000);
Console.WriteLine("World!");

Código de salida para el proceso

Para devolver un valor int cuando finaliza la aplicación, use la instrucción return como lo haría en un método Main que devuelva una instancia de int. Por ejemplo:

string? s = Console.ReadLine();

int returnValue = int.Parse(s ?? "-1");
return returnValue;

Método de punto de entrada implícito

El compilador genera un método que actúa como el punto de entrada del programa para un proyecto con instrucciones de nivel superior. La signatura del método depende de si las instrucciones de nivel superior contienen la palabra clave await o la instrucción return. En la tabla siguiente se muestra el aspecto que tendría la signatura del método, utilizando el nombre del método Main en la tabla para mayor comodidad.

El código de nivel superior contiene Signatura de Main implícita
await y return static async Task<int> Main(string[] args)
await static async Task Main(string[] args)
return static int Main(string[] args)
No await ni return static void Main(string[] args)

Especificación del lenguaje C#

Para obtener más información, consulte la Especificación del lenguaje C#. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.

Especificación de la característica: instrucciones de nivel superior