Main()과 명령줄 인수
Main
메서드는 C# 애플리케이션의 진입점입니다. 애플리케이션이 시작될 때 Main
메서드는 호출되는 첫 번째 메서드입니다.
C# 프로그램에는 하나의 진입점만 있을 수 있습니다. Main
메서드가 있는 클래스가 둘 이상 있는 경우 StartupObject 컴파일러 옵션으로 프로그램을 컴파일하여 진입점으로 사용할 Main
메서드를 지정해야 합니다. 자세한 내용은 StartupObject(C# 컴파일러 옵션)를 참조하세요.
class TestClass
{
static void Main(string[] args)
{
// Display the number of command line arguments.
Console.WriteLine(args.Length);
}
}
한 파일의 최상위 문을 애플리케이션의 진입점으로 사용할 수도 있습니다.
Main
메서드와 마찬가지로 최상위 문은 값을 반환하고 명령줄 인수에 액세스할 수도 있습니다.
자세한 내용은 최상위 문을 참조하세요.
using System.Text;
StringBuilder builder = new();
builder.AppendLine("The following arguments are passed:");
// Display the command line arguments using the args variable.
foreach (var arg in args)
{
builder.AppendLine($"Argument={arg}");
}
Console.WriteLine(builder.ToString());
// Return a success code.
return 0;
개요
Main
메서드는 실행 가능한 프로그램의 진입점으로, 프로그램의 제어가 시작되고 끝나는 위치합니다.Main
은 클래스 또는 구조체 내에서 선언되어야 합니다. 바깥쪽class
는static
일 수 있습니다.Main
해야static
합니다.Main
는 액세스 한정자를 가질 수 있습니다(file
제외).Main
은void
,int
,Task
또는Task<int>
반환 형식을 가질 수 있습니다.Main
에서Task
또는Task<int>
을 반환하는 경우에만Main
선언에async
한정자가 포함될 수 있습니다. 이는 특히async void Main
메서드를 제외합니다.Main
메서드는 명령줄 인수를 포함하는string[]
매개 변수 사용 여부에 관계 없이 선언될 수 있습니다. Visual Studio를 사용하여 Windows 애플리케이션을 만드는 경우 매개 변수를 수동으로 추가하거나 GetCommandLineArgs() 메서드를 사용하여 명령줄 인수를 가져올 수 있습니다. 매개 변수는 0부터 시작하는 명령줄 인수로 읽힙니다. C 및 C++와 달리, 프로그램의 이름이args
배열의 첫 번째 명령줄 인수로 처리되지 않지만, GetCommandLineArgs() 메서드의 첫 번째 요소입니다.
다음 목록에서는 가장 일반적인 Main
선언을 보여줍니다.
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) { }
앞의 예제에서는 액세스 한정자를 지정하지 않으므로 기본적으로 암시적으로 private
입니다. 그것이 일반적이지만, 명시적 액세스 한정자를 지정할 수도 있습니다.
팁
async
및 Task
, Task<int>
반환 형식을 추가하면 콘솔 애플리케이션을 시작해야 하고 비동기 작업을 Main
에서 await
해야 하는 경우에 프로그램 코드가 간소화됩니다.
Main() 반환 값
다음 방법 중 하나로 메서드를 정의하여 Main
메서드에서 int
를 반환할 수 있습니다.
Main 선언 |
Main 메서드 코드 |
---|---|
static int Main() |
args 또는 await 사용 안 함 |
static int Main(string[] args) |
args 사용, await 사용 안 함 |
static async Task<int> Main() |
args 사용 안 함 , await 사용 |
static async Task<int> Main(string[] args) |
args 및 await 사용 |
Main
의 반환 값을 사용하지 않는 경우 void
또는 Task
를 반환하면 코드가 다소 단순해집니다.
Main 선언 |
Main 메서드 코드 |
---|---|
static void Main() |
args 또는 await 사용 안 함 |
static void Main(string[] args) |
args 사용, await 사용 안 함 |
static async Task Main() |
args 사용 안 함 , await 사용 |
static async Task Main(string[] args) |
args 및 await 사용 |
그러나 int
또는 Task<int>
를 반환하면 프로그램이 실행 파일을 호출하는 다른 프로그램이나 스크립트에 상태 정보를 전달할 수 있습니다.
다음 예제에서는 프로세스의 종료 코드에 액세스할 수 있는 방법을 보여줍니다.
이 예제에서는 .NET Core 명령줄 도구를 사용합니다. .NET Core 명령줄 도구에 대해 잘 모르는 경우 이 시작 문서에서 알아볼 수 있습니다.
dotnet new console
을 실행하여 새 애플리케이션을 만듭니다. Program.cs 에서 Main
메서드를 다음과 같이 수정합니다.
// Save this program as MainReturnValTest.cs.
class MainReturnValTest
{
static int Main()
{
//...
return 0;
}
}
Windows에서 프로그램을 실행하는 경우 Main
함수에서 반환된 값은 환경 변수에 저장됩니다. 이 환경 변수는 배치 파일에서 ERRORLEVEL
을 사용하거나 PowerShell에서 $LastExitCode
를 사용하여 검색할 수 있습니다.
dotnet CLI dotnet build
명령을 사용하여 애플리케이션을 빌드할 수 있습니다.
다음으로 애플리케이션을 실행하고 결과를 표시하는 PowerShell 스크립트를 만듭니다. 다음 코드를 텍스트 파일에 붙여넣고 이 파일을 프로젝트가 포함된 폴더에 test.ps1
로 저장합니다. PowerShell 프롬프트에 test.ps1
을 입력하여 PowerShell 스크립트를 실행합니다.
코드에서 0을 반환하기 때문에 배치 파일이 성공했다고 보고합니다. 그러나 0이 아닌 값을 반환하도록 MainReturnValTest.cs를 변경한 다음 프로그램을 다시 컴파일하면 다음에 PowerShell 스크립트를 실행할 때 오류가 보고됩니다.
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
비동기 Main 반환 값
Main
에 대한 async
반환 값을 선언하면 컴파일러는 Main
에서 비동기 메서드를 호출하기 위한 상용구 코드를 생성합니다. async
키워드를 지정하지 않으면 다음 예와 같이 해당 코드를 직접 작성해야 합니다. 예의 코드는 비동기 작업이 완료될 때까지 프로그램이 실행되도록 보장합니다.
class AsyncMainReturnValTest
{
public static int Main()
{
return AsyncConsoleWork().GetAwaiter().GetResult();
}
private static async Task<int> AsyncConsoleWork()
{
// Main body here
return 0;
}
}
이 상용구 코드는 다음으로 바뀔 수 있습니다.
class Program
{
static async Task<int> Main(string[] args)
{
return await AsyncConsoleWork();
}
private static async Task<int> AsyncConsoleWork()
{
// main body here
return 0;
}
}
Main
을 async
로 선언하면 컴파일러가 항상 올바른 코드를 생성한다는 이점이 있습니다.
애플리케이션 진입점에서 Task
또는 Task<int>
를 반환하는 경우 컴파일러는 애플리케이션 코드에서 선언된 진입점 메서드를 호출하는 새 진입점을 생성합니다. 이 진입점이 $GeneratedMain
이라고 가정하면 컴파일러는 이러한 진입점에 대해 다음 코드를 생성합니다.
static Task Main()
- 컴파일러에서private static void $GeneratedMain() => Main().GetAwaiter().GetResult();
에 해당하는 코드를 내보냅니다.static Task Main(string[])
- 컴파일러에서private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
에 해당하는 코드를 내보냅니다.static Task<int> Main()
- 컴파일러에서private static int $GeneratedMain() => Main().GetAwaiter().GetResult();
에 해당하는 코드를 내보냅니다.static Task<int> Main(string[])
- 컴파일러에서private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
에 해당하는 코드를 내보냅니다.
참고 항목
예제에서 Main
메서드에 async
한정자를 사용하더라도 컴파일러는 동일한 코드를 생성합니다.
명령줄 인수
다음 방법 중 하나로 메서드를 정의하여 인수를 Main
메서드에 보낼 수 있습니다.
Main 선언 |
Main 메서드 코드 |
---|---|
static void Main(string[] args) |
반환 값 없음, await 사용 없음 |
static int Main(string[] args) |
반환 값, await 사용 없음 |
static async Task Main(string[] args) |
반환 값 없음, await 사용 |
static async Task<int> Main(string[] args) |
반환 값, await 사용 |
인수가 사용되지 않는 경우 약간 더 간단한 코드를 위해 메서드 선언에서 args
를 생략할 수 있습니다.
Main 선언 |
Main 메서드 코드 |
---|---|
static void Main() |
반환 값 없음, await 사용 없음 |
static int Main() |
반환 값, await 사용 없음 |
static async Task Main() |
반환 값 없음, await 사용 |
static async Task<int> Main() |
반환 값, await 사용 |
참고 항목
Environment.CommandLine 또는 Environment.GetCommandLineArgs를 사용하여 콘솔 또는 Windows Forms 애플리케이션의 임의 지점에서 명령줄 인수에 액세스할 수 있습니다. Windows Forms 애플리케이션의 Main
메서드 선언에서 명령줄 인수를 사용하려면 Main
선언을 수동으로 수정해야 합니다. Windows Forms 디자이너에서 생성된 코드는 입력 매개 변수 없이 Main
을 만듭니다.
Main
메서드의 매개 변수는 명령줄 인수를 나타내는 String 배열입니다. 일반적으로 다음과 같이 Length
속성을 테스트하여 인수가 있는지 확인합니다.
if (args.Length == 0)
{
System.Console.WriteLine("Please enter a numeric argument.");
return 1;
}
팁
args
배열은 null일 수 없습니다. 따라서 null 검사 없이 Length
속성에 액세스하는 것이 안전합니다.
Convert 클래스 또는 Parse
메서드를 사용하여 문자열 인수를 숫자 형식으로 변환할 수도 있습니다. 예를 들어 다음 문은 Parse 메서드를 사용하여 string
을 long
숫자로 변환합니다.
long num = Int64.Parse(args[0]);
Int64
의 별칭을 지정하는 C# 형식 long
을 사용할 수도 있습니다.
long num = long.Parse(args[0]);
Convert
클래스 메서드 ToInt64
를 사용하여 같은 작업을 수행할 수도 있습니다.
long num = Convert.ToInt64(s);
자세한 내용은 Parse 및 Convert를 참조하세요.
팁
명령줄 인수 구문 분석은 복잡할 수 있습니다. 프로세스를 간소화하려면 System.CommandLine 라이브러리(현재 베타)를 사용하는 것이 좋습니다.
다음 예제에서는 콘솔 애플리케이션에서 명령줄 인수를 사용하는 방법을 보여 줍니다. 애플리케이션은 런타임에 하나의 인수를 사용하고, 인수를 정수로 변환하고, 숫자의 계승을 계산합니다. 인수가 제공되지 않으면 애플리케이션에서는 프로그램의 올바른 사용법을 설명하는 메시지를 표시합니다.
명령 프롬프트에서 애플리케이션을 컴파일 및 실행하려면 다음 단계를 수행합니다.
다음 코드를 텍스트 편집기에 붙여넣고 이름 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) { // Test if input arguments were supplied. if (args.Length == 0) { Console.WriteLine("Please enter a numeric argument."); Console.WriteLine("Usage: Factorial <num>"); return 1; } // Try to convert the input arguments to numbers. This will throw // an exception if the argument is not a number. // num = int.Parse(args[0]); 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; } // Calculate factorial. long result = Functions.Factorial(num); // Print result. if (result == -1) Console.WriteLine("Input must be >= 0 and <= 20."); else Console.WriteLine($"The Factorial of {num} is {result}."); return 0; } } // If 3 is entered on command line, the // output reads: The factorial of 3 is 6.
시작 화면이나 시작 메뉴에서 Visual Studio 개발자 명령 프롬프트 창을 열고 만든 파일이 포함된 폴더로 이동합니다.
다음 명령을 입력하여 애플리케이션을 컴파일합니다.
dotnet build
애플리케이션에 컴파일 오류가 없으면 Factorial.exe라는 실행 파일이 만들어집니다.
다음 명령을 입력하여 3의 계승을 계산합니다.
dotnet run -- 3
이 명령은 다음 출력을 생성합니다.
The factorial of 3 is 6.
참고 항목
Visual Studio에서 애플리케이션을 실행할 경우 프로젝트 디자이너, 디버그 페이지에서 명령줄 인수를 지정할 수 있습니다.
C# 언어 사양
자세한 내용은 C# 언어 사양을 참조하세요. 언어 사양은 C# 구문 및 사용법에 대 한 신뢰할 수 있는 소스 됩니다.
참고 항목
.NET