Sdílet prostřednictvím


Main() a argumenty příkazového řádku

Modul runtime volá metodu Main při spuštění aplikace jazyka C#. Metoda Main je vstupním bodem aplikace jazyka C#.

Program jazyka C# může mít pouze jeden vstupní bod. Pokud máte více než jednu třídu s metodou Main , musíte při kompilaci programu použít možnost kompilátoru StartupObject určit, která Main metoda slouží jako vstupní bod. Další informace naleznete v tématu StartupObject (možnosti kompilátoru jazyka C#). Následující příklad zobrazí počet argumentů příkazového řádku jako první akci:

class TestClass
{
    static void Main(string[] args)
    {
        Console.WriteLine(args.Length);
    }
}

Příkazy nejvyšší úrovně můžete použít také v jednom souboru jako vstupní bod pro vaši aplikaci. Stejně jako u Main metody můžou příkazy nejvyšší úrovně vracet hodnoty a přistupovat k argumentům příkazového řádku. Další informace najdete v tématu Příkazy nejvyšší úrovně. Následující příklad používá smyčku foreach k zobrazení argumentů příkazového řádku pomocí args proměnné a na konci programu vrátí kód úspěchu (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;

Počínaje jazykem C# 14 můžou být aplikace založené na souborech, kde jeden soubor obsahuje program. Aplikace založené na souborech spouštíte pomocí příkazu dotnet <file.cs>nebo pomocí #!/usr/bin/env dotnet run direktivy jako prvního řádku (pouze unixové prostředí).

Přehled

  • Metoda Main je vstupním bodem spustitelného programu. Je to místo, kde ovládací prvek programu začíná a končí.
  • Musíte deklarovat Main uvnitř třídy nebo struktury. Uzavření class může být static.
  • Main musí být static.
  • Main může mít libovolný modifikátor přístupu.
  • Mainmůže vrátit void, , intTasknebo Task<int>.
  • Pokud a pouze pokud Main vrátí Task nebo Task<int>, může deklarace Main zahrnovat modifikátor async. Toto pravidlo výslovně vylučuje metodu async void Main .
  • Metodu Main můžete deklarovat pomocí nebo bez parametru string[] , který obsahuje argumenty příkazového řádku. Při vytváření aplikací pro Windows pomocí sady Visual Studio můžete parametr přidat ručně nebo použít metodu GetCommandLineArgs() k získání argumentů příkazového řádku. Parametry jsou argumenty příkazového řádku indexované nulou. Na rozdíl od jazyka C a C++ není název programu považován za první argument příkazového řádku v args poli, ale je to první prvek GetCommandLineArgs() metody.

V následujícím seznamu jsou uvedeny nejběžnější Main deklarace:

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) { }

Předchozí příklady nezadávají modifikátor přístupu, takže jsou implicitně private ve výchozím nastavení. Můžete zadat libovolný modifikátor explicitního přístupu.

Návod

Pomocí návratových typů async a Task zjednodušíte programový kód, když konzolové aplikace potřebují spouštět a asynchronní operace v Task<int>await.

Návratové hodnoty Main()

V metodě int můžete vrátit Main definováním metody některým z následujících způsobů:

Main prohlášení Main kód metody
static int Main() Žádné použití args nebo await
static int Main(string[] args) Používá se args , ale ne await
static async Task<int> Main() Používá se await , ale ne args
static async Task<int> Main(string[] args) Používá args a await

Pokud se návratová hodnota z Main nepoužívá, vrácení void nebo Task umožní mírně jednodušší kód.

Main prohlášení Main kód metody
static void Main() Žádné použití args nebo await
static void Main(string[] args) Používá se args , ale ne await
static async Task Main() Používá se await , ale ne args
static async Task Main(string[] args) Používá args a await

Vrácení int nebo Task<int> však umožňuje programu sdělit informace o stavu jiným programům nebo skriptům, které vyvolávají spustitelný soubor.

Následující příklad ukazuje, jak lze získat přístup k ukončovacímu kódu procesu.

V tomto příkladu se používají nástroje příkazového řádku .NET Core . Pokud neznáte nástroje příkazového řádku .NET Core, můžete se o nich dozvědět v tomto článku začínáme.

Vytvořte novou aplikaci spuštěním dotnet new consolepříkazu . Upravte metodu Main v Program.cs následujícím způsobem:

class MainReturnValTest
{
    static int Main()
    {
        //...
        return 0;
    }
}

Nezapomeňte tento program uložit jako MainReturnValTest.cs.

Když spustíte program ve Windows, systém uloží libovolnou hodnotu vrácenou Main z funkce do proměnné prostředí. Tuto proměnnou prostředí můžete načíst pomocí příkazu ERRORLEVEL z dávkového souboru nebo příkazu $LastExitCode z PowerShellu.

Aplikaci můžete sestavit pomocí příkazu dotnet CLIdotnet build .

Dále vytvořte skript PowerShellu pro spuštění aplikace a zobrazte výsledek. Vložte následující kód do textového souboru a uložte ho jako test.ps1 do složky, která obsahuje projekt. Spusťte skript PowerShellu zadáním test.ps1 na příkazovém řádku PowerShellu.

Protože kód vrátí nulu, dávkový soubor hlásí úspěch. Pokud ale změníte MainReturnValTest.cs tak, aby vracela nenulovou hodnotu a pak program znovu zkompilovat, následné spuštění skriptu PowerShellu hlásí selhání.

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

Asynchronní hlavní návratové hodnoty

Když deklarujete async návratovou hodnotu, Main kompilátor vygeneruje vzorový kód pro volání asynchronních metod v Main:

class Program
{
    static async Task<int> Main(string[] args)
    {
        return await AsyncConsoleWork();
    }

    private static async Task<int> AsyncConsoleWork()
    {
        return 0;
    }
}

V obou příkladech je hlavní tělo programu v těle AsyncConsoleWork() metody.

Výhodou deklarování Main jako async je, že kompilátor vždy generuje správný kód.

Když vstupní bod aplikace vrátí nebo TaskTask<int>, kompilátor vygeneruje nový vstupní bod, který volá metodu vstupního bodu deklarovanou v kódu aplikace. Za předpokladu, že se tento vstupní bod nazývá $GeneratedMain, kompilátor vygeneruje následující kód pro tyto vstupní body:

  • static Task Main() vede k tomu, že kompilátor vygeneruje ekvivalent private static void $GeneratedMain() => Main().GetAwaiter().GetResult();.
  • static Task Main(string[]) vede k tomu, že kompilátor vygeneruje ekvivalent private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();.
  • static Task<int> Main() vede k tomu, že kompilátor vygeneruje ekvivalent private static int $GeneratedMain() => Main().GetAwaiter().GetResult();.
  • static Task<int> Main(string[]) vede k tomu, že kompilátor vygeneruje ekvivalent private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();.

Poznámka:

Pokud příklady používají async modifikátor metody Main , kompilátor vygeneruje stejný kód.

Argumenty příkazového řádku

Argumenty metody Main můžete odeslat definováním metody jedním z následujících způsobů:

Main prohlášení Main kód metody
static void Main(string[] args) Žádná návratová hodnota nebo await
static int Main(string[] args) Vrátí hodnotu, ale nepoužívá await.
static async Task Main(string[] args) Použije await , ale nevrací hodnotu.
static async Task<int> Main(string[] args) Vrací hodnotu a používá await

Pokud argumenty nepoužíváte, můžete z deklarace metody vynechat args trochu jednodušší kód:

Main prohlášení Main kód metody
static void Main() Žádná návratová hodnota nebo await
static int Main() Vrátí hodnotu, ale nepoužívá await.
static async Task Main() Použije await , ale nevrací hodnotu.
static async Task<int> Main() Vrátí hodnotu a použije await

Poznámka:

Můžete také použít Environment.CommandLine nebo Environment.GetCommandLineArgs, abyste přistupovali k argumentům příkazového řádku z libovolného bodu konzolové nebo Windows Forms aplikace. Chcete-li povolit argumenty příkazového řádku v Main deklaraci metody v aplikaci model Windows Forms, je nutné ručně upravit deklaraci Main. Kód vygenerovaný návrhářem Windows Forms vytvoří Main bez vstupního parametru.

Parametr Main metody je String pole, které představuje argumenty příkazového řádku. Obvykle určíte, jestli argumenty existují testováním Length vlastnosti, například:

if (args.Length == 0)
{
    System.Console.WriteLine("Please enter a numeric argument.");
    return 1;
}

Návod

Pole args nemůže mít hodnotu null. Je tedy bezpečné přistupovat k Length vlastnosti bez kontroly null.

Řetězcové argumenty můžete také převést na číselné typy pomocí Convert třídy nebo Parse metody. Například následující příkaz převede string na číslo long pomocí metody Parse:

long num = Int64.Parse(args[0]);

Je také možné použít typ long jazyka C#, což je alias Int64.

long num = long.Parse(args[0]);

Stejnou věc můžete provést také pomocí Convert metody ToInt64 třídy:

long num = Convert.ToInt64(s);

Další informace najdete v tématech Parse a Convert.

Návod

Analýza argumentů příkazového řádku může být složitá. Zvažte použití knihovny System.CommandLine ke zjednodušení procesu.

Následující příklad ukazuje, jak používat argumenty příkazového řádku v konzolové aplikaci. Aplikace vezme jeden argument za běhu, převede argument na celé číslo a vypočítá faktoriál čísla. Pokud nejsou zadány žádné argumenty, aplikace vydá zprávu, která vysvětluje správné použití programu.

Pokud chcete aplikaci zkompilovat a spustit z příkazového řádku, postupujte takto:

  1. Do libovolného textového editoru vložte následující kód a uložte ho jako textový soubor s názvem 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;
    }
}

Na začátku Main metody program testuje, zda vstupní argumenty nebyly zadány porovnáním délky argumentu args0 a zobrazení nápovědy, pokud nebyly nalezeny žádné argumenty.
Pokud jsou zadány argumenty (args.Length je větší než 0), program se pokusí převést vstupní argumenty na čísla. Tento příklad vyvolá výjimku, pokud argument není číslo.
Po výpočtu faktoriálu (uloženého v result proměnné typu long) se v závislosti na result proměnné vytiskne podrobný výsledek.

  1. V nabídce Start nebo Start otevřete okno příkazového řádku pro vývojáře sady Visual Studio a přejděte do složky, která obsahuje soubor, který jste vytvořili.

  2. Pokud chcete aplikaci zkompilovat, zadejte následující příkaz:

    dotnet build

    Pokud vaše aplikace nemá žádné chyby kompilace, proces sestavení vytvoří binární soubor s názvem Factorial.dll.

  3. Zadejte následující příkaz pro výpočet faktoriálu 3:

    dotnet run -- 3

  4. Pokud jako argument programu zadáte 3 na příkazovém řádku, výstup přečte: The factorial of 3 is 6.

Poznámka:

Při spuštění aplikace v sadě Visual Studio zadejte argumenty příkazového řádku na stránce Ladění, Návrhář projektu.

specifikace jazyka C#

Další informace najdete v tématu Specifikace jazyka C#. Specifikace jazyka je úplným a rozhodujícím zdrojem pro syntaxi a použití jazyka C#.

Viz také