Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
El método Main es el punto de entrada de una aplicación de C# Cuando se inicia la aplicación, el método Main es el primero que se invoca.
Solo puede haber un punto de entrada en un programa de C#. Si hay más de una clase que tenga un método Main, deberá compilar el programa con la opción del compilador StartupObject para especificar qué método Main quiere utilizar como punto de entrada. Para obtener más información, consulte StartupObject (opciones del compilador de C#). En el ejemplo siguiente se muestra el número de argumentos de la línea de comandos como su primera acción:
class TestClass
{
static void Main(string[] args)
{
Console.WriteLine(args.Length);
}
}
También puede usar instrucciones de nivel superior en un archivo como punto de entrada para la aplicación. Al igual que el método Main, las instrucciones de nivel superior también pueden devolver valores y acceder a los argumentos de la línea de comandos. Para más información, consulte Instrucciones de nivel superior. En el ejemplo siguiente se usa un foreach bucle para mostrar los argumentos de la línea de comandos mediante la args variable y al final del programa se devuelve un código correcto (0):
using System.Text;
StringBuilder builder = new();
builder.AppendLine("The following arguments are passed:");
foreach (var arg in args)
{
builder.AppendLine($"Argument={arg}");
}
Console.WriteLine(builder.ToString());
return 0;
A partir de C# 14, los programas pueden ser aplicaciones basadas en archivos, donde un único archivo contiene el programa. Las aplicaciones basadas en archivos se ejecutan con el comando dotnet run <file.cs>o se usa la #!/usr/local/share/dotnet/dotnet run directiva como primera línea (solo shells de Unix).
Información general
- El
Mainmétodo es el punto de entrada de un programa ejecutable; es donde se inicia y finaliza el control de programa. -
Maindebe declararse dentro de una clase o estructura. Laclassenvolvente puede serstatic. -
Maindebe serstatic. -
Mainpuede tener cualquier modificador de acceso (exceptofile). -
Mainpuede tener un tipo de valor devueltovoid,int,TaskoTask<int>. - Si y solo si
Maindevuelve unTasko unTask<int>, la declaración deMainpuede incluir el modificadorasync. Esta regla excluye específicamente unasync void Mainmétodo . - El método
Mainse puede declarar con o sin un parámetrostring[]que contiene los argumentos de línea de comandos. Al usar Visual Studio para crear aplicaciones Windows, se puede agregar el parámetro manualmente o usar el método GetCommandLineArgs() con el fin de obtener los argumentos de la línea de comandos. Los parámetros se leen como argumentos de línea de comandos indizados con cero. A diferencia de C y C++, el nombre del programa no se trata como el primer argumento de línea de comandos de laargsmatriz, pero es el primer elemento del GetCommandLineArgs() método.
En la lista siguiente, se muestran las declaraciones Main más comunes:
static void Main() { }
static int Main() { }
static void Main(string[] args) { }
static int Main(string[] args) { }
static async Task Main() { }
static async Task<int> Main() { }
static async Task Main(string[] args) { }
static async Task<int> Main(string[] args) { }
Los ejemplos anteriores no especifican un modificador de acceso, por lo que son implícitamente private de forma predeterminada. Es posible especificar cualquier modificador de acceso explícito.
Sugerencia
Al agregar los tipos de valor devuelto async, Task y Task<int>, se simplifica el código de programa cuando las aplicaciones de consola tienen que realizar tareas de inicio y await de operaciones asincrónicas en Main.
Valores devueltos por Main()
Puede devolver un objeto int desde el método Main si lo define de una de las siguientes maneras:
Declaración Main |
Código del método Main |
|---|---|
static int Main() |
No se usa args ni await |
static int Main(string[] args) |
Usa args , pero no await |
static async Task<int> Main() |
Usa await , pero no args |
static async Task<int> Main(string[] args) |
Se usan args y await |
Si no se usa el valor devuelto de Main , devuelve void o Task permite un código ligeramente más sencillo.
Declaración Main |
Código del método Main |
|---|---|
static void Main() |
No se usa args ni await |
static void Main(string[] args) |
Usa args , pero no await |
static async Task Main() |
Usa await , pero no args |
static async Task Main(string[] args) |
Se usan args y await |
Pero, si se devuelve int o Task<int>, el programa puede comunicar información de estado a otros programas o scripts que invocan el archivo ejecutable.
En el ejemplo siguiente se muestra cómo se puede acceder al código de salida para el proceso.
En este ejemplo se usan las herramientas de línea de comandos de .NET Core. Si no está familiarizado con las herramientas de línea de comandos de .NET Core, puede obtener información sobre ellas en este artículo de introducción.
Cree una aplicación mediante la ejecución de dotnet new console. Modifique el método Main en Program.cs como se indica a continuación:
class MainReturnValTest
{
static int Main()
{
//...
return 0;
}
}
Recuerde guardar este programa como MainReturnValTest.cs.
Cuando un programa se ejecuta en Windows, cualquier valor devuelto por la función Main se almacena en una variable de entorno. Esta variable de entorno se puede recuperar mediante ERRORLEVEL desde un archivo por lotes, o mediante $LastExitCode desde PowerShell.
Puede compilar la aplicación mediante el comando de la CLI de dotnetdotnet build.
Después, cree un script de PowerShell para ejecutar la aplicación y mostrar el resultado. Pegue el código siguiente en un archivo de texto y guárdelo como test.ps1 en la carpeta que contiene el proyecto. Ejecute el script de PowerShell escribiendo test.ps1 en PowerShell.
Dado que el código devuelve cero, el archivo por lotes informa de un éxito. Sin embargo, si cambia MainReturnValTest.cs para devolver un valor distinto de cero y, a continuación, volver a compilar el programa, la ejecución posterior del script de PowerShell notifica un error.
dotnet run
if ($LastExitCode -eq 0) {
Write-Host "Execution succeeded"
} else
{
Write-Host "Execution Failed"
}
Write-Host "Return value = " $LastExitCode
Execution succeeded
Return value = 0
Valores devueltos asincrónicos de Main
Cuando se declara un valor devuelto async para Main, el compilador genera el código reutilizable para llamar a métodos asincrónicos en Main:
class Program
{
static async Task<int> Main(string[] args)
{
return await AsyncConsoleWork();
}
private static async Task<int> AsyncConsoleWork()
{
return 0;
}
}
En ambos ejemplos el cuerpo principal del programa está dentro del cuerpo del método AsyncConsoleWork().
Una ventaja de declarar Main como async es que el compilador siempre genera el código correcto.
Cuando el punto de entrada de la aplicación devuelve Task o Task<int>, el compilador genera un nuevo punto de entrada que llama al método de punto de entrada declarado en el código de la aplicación. Suponiendo que este punto de entrada se denomina $GeneratedMain, el compilador genera el código siguiente para estos puntos de entrada:
-
static Task Main()hace que el compilador emita el equivalente deprivate static void $GeneratedMain() => Main().GetAwaiter().GetResult(); -
static Task Main(string[])hace que el compilador emita el equivalente deprivate static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult(); -
static Task<int> Main()hace que el compilador emita el equivalente deprivate static int $GeneratedMain() => Main().GetAwaiter().GetResult(); -
static Task<int> Main(string[])hace que el compilador emita el equivalente deprivate static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
Nota
Si en los ejemplos se usase el modificador async en el método Main, el compilador generaría el mismo código.
Argumentos de la línea de comandos
Puede enviar argumentos al método Main definiéndolo de una de las siguientes maneras:
Declaración Main |
Código del método Main |
|---|---|
static void Main(string[] args) |
No devuelve ningún valor o await |
static int Main(string[] args) |
Devuelve un valor, pero no usa await |
static async Task Main(string[] args) |
Usa await pero no devuelve un valor |
static async Task<int> Main(string[] args) |
Devolver un valor y usar await |
Si no se utilizan los argumentos, puede omitir args de la declaración del método para un código ligeramente más sencillo.
Declaración Main |
Código del método Main |
|---|---|
static void Main() |
No devuelve ningún valor o await |
static int Main() |
Devuelve un valor, pero no usa await |
static async Task Main() |
Usa await pero no devuelve un valor |
static async Task<int> Main() |
Devuelve un valor y usa await |
Nota
También puede usar Environment.CommandLine o Environment.GetCommandLineArgs para acceder a los argumentos de la línea de comandos desde cualquier punto de una consola o de una aplicación de Windows Forms. Para habilitar los argumentos de la línea de comandos en la declaración del método Main de una aplicación Windows Forms, tendrá que modificar manualmente la declaración de Main. El código generado por el diseñador de Windows Forms crea un Main sin ningún parámetro de entrada.
El parámetro del método Main es una matriz String que representa los argumentos de la línea de comandos. Normalmente, para determinar si hay argumentos, se prueba la propiedad Length; por ejemplo:
if (args.Length == 0)
{
System.Console.WriteLine("Please enter a numeric argument.");
return 1;
}
Sugerencia
La matriz args no puede ser NULL. así que es seguro acceder a la propiedad Length sin comprobar los valores NULL.
También puede convertir los argumentos de cadena en tipos numéricos mediante la clase Convert o el método Parse. Por ejemplo, la siguiente instrucción convierte la string en un número long mediante el método Parse:
long num = Int64.Parse(args[0]);
También es posible usar el tipo long de C#, cual es un alias de Int64.
long num = long.Parse(args[0]);
También puede usar el método Convert de la clase ToInt64 para hacer lo mismo:
long num = Convert.ToInt64(s);
Para obtener más información, vea Parse y Convert.
Sugerencia
El análisis de argumentos de línea de comandos puede ser complejo. Considere la posibilidad de usar la biblioteca System.CommandLine (actualmente en versión beta) para simplificar el proceso.
En el ejemplo siguiente se muestra cómo usar argumentos de la línea de comandos en una aplicación de consola. La aplicación toma un argumento en tiempo de ejecución, lo convierte en un entero y calcula el factorial del número. Si no se proporciona ningún argumento, la aplicación emite un mensaje en el que se explica el uso correcto del programa.
Para compilar y ejecutar la aplicación desde un terminal, siga estos pasos:
Pegue el código siguiente en cualquier editor de texto, y después guarde el archivo como archivo de texto con el nombre Factorial.cs.
public class Functions { public static long Factorial(int n) { // Test for invalid input. if ((n < 0) || (n > 20)) { return -1; } // Calculate the factorial iteratively rather than recursively. long tempResult = 1; for (int i = 1; i <= n; i++) { tempResult *= i; } return tempResult; } } class MainClass { static int Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Please enter a numeric argument."); Console.WriteLine("Usage: Factorial <num>"); return 1; } int num; bool test = int.TryParse(args[0], out num); if (!test) { Console.WriteLine("Please enter a numeric argument."); Console.WriteLine("Usage: Factorial <num>"); return 1; } long result = Functions.Factorial(num); if (result == -1) Console.WriteLine("Input must be >= 0 and <= 20."); else Console.WriteLine($"The Factorial of {num} is {result}."); return 0; } }Al principio del
Mainmétodo, el programa comprueba si no se proporcionaron argumentos de entrada que comparan la longitud delargsargumento con0y muestra la ayuda si no se encuentra ningún argumento.
Si se proporcionan argumentos (args.Lengthes mayor que 0), el programa intenta convertir los argumentos de entrada en números. En este ejemplo se produce una excepción si el argumento no es un número.
Una vez calculado el factorial (almacenado enresultde la variable de tipolong), el resultado detallado se imprime en función de la variableresult.En la pantalla Inicio o en el menú Inicio, abra una ventana del Símbolo del sistema para desarrolladores de Visual Studio y navegue hasta la carpeta que contiene el archivo que creó.
Para compilar la aplicación, escriba el siguiente comando:
dotnet buildSi la aplicación no tiene errores de compilación, se crea un archivo binario denominado Factorial.dll .
Escriba el siguiente comando para calcular el factorial de 3:
dotnet run -- 3Si se escribe 3 en la línea de comandos como argumento del programa, la salida lee:
The factorial of 3 is 6.
Nota
Al ejecutar una aplicación en Visual Studio, puede especificar argumentos de la línea de comandos en la Página Depuración, Diseñador de proyectos.
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#.