전통적인 첫 프로그램은 텍스트 한 줄을 출력합니다. C#에서는 이렇게 씁니다:
출력:
Hello, World!
한 줄씩 살펴보기
using System;덕분에 전체 이름System.Console대신Console이라고 쓸 수 있습니다.Console은System네임스페이스에 있는 클래스입니다(네임스페이스와 using 참고).class Program은 클래스를 선언합니다. 모든 C# 코드는 타입 안에 있으며,Program이라는 이름은 관례일 뿐 필수는 아닙니다.static void Main()은 진입점입니다. 프로그램이 시작되면 런타임은Main이라는 정적 메서드를 찾아 호출합니다.static은 메서드가 클래스 자체에 속한다는 뜻이라 객체를 먼저 만들 필요가 없습니다.void는 아무것도 반환하지 않는다는 뜻입니다.Console.WriteLine("Hello, World!");는 문자열 인수로WriteLine메서드를 호출합니다. 모든 문장은 세미콜론으로 끝납니다.- 중괄호
{ }는 클래스와 메서드의 본문을 표시합니다.
C#은 대소문자를 구분합니다. console.writeline과 main은 Console.WriteLine, Main과 다른 이름이며, 둘 다 존재하지 않습니다.
Console.WriteLine과 Console.Write
WriteLine은 텍스트 뒤에 줄바꿈을 붙입니다. Write는 붙이지 않으므로 다음 출력이 같은 줄에 이어집니다. 둘 다 문자열뿐 아니라 어떤 타입이든 받습니다. 숫자, 불리언, 객체는 ToString() 메서드로 변환됩니다.
출력:
Loading.. done
42
True
Item: coffee
coffee costs 3.20
coffee costs 3.20
true가 True로 출력되는 점에 주목하세요. bool.ToString()이 그렇게 반환하기 때문입니다. 문자열 보간이라고 부르는 $"..." 형태를 가장 많이 쓰게 됩니다. :F2 같은 서식 코드는 문자열 보간을 참고하세요.
Console.ReadLine으로 입력 받기
Console.ReadLine()은 사용자가 한 줄을 입력하고 Enter를 누를 때까지 기다렸다가, 그 줄을 줄바꿈 없이 string으로 반환합니다. 입력이 끝나면(예를 들어 파일에서 리디렉션한 입력이 다 떨어지면) null을 반환합니다.
출력:
What is your name? How old are you?
Hi Maya, next year you will be 28.
터미널에서 실행하면 입력한 텍스트가 각 안내 문구 뒤에 나타납니다. 위 출력에 입력한 텍스트가 없는 이유는 직접 입력하지 않고 리디렉션(파이프)으로 입력을 넣었기 때문이며, 그래서 프로그램이 직접 쓴 내용만 보입니다.
ReadLine은 항상 텍스트를 반환합니다. 값을 숫자로 쓰려면 변환해야 합니다. int.Parse(text)는 텍스트가 숫자가 아니면 FormatException을 던지고, int.TryParse는 대신 false를 반환하므로 사용자 입력에는 이쪽이 맞습니다. 자세한 내용은 형 변환에 있습니다.
관련 메서드가 두 가지 더 있습니다. Console.Read()는 다음 문자를 int 코드로 반환하고, Console.ReadKey()는 Enter를 기다리지 않고 키 하나를 읽습니다(대화형 터미널에서만 동작합니다).
Main 메서드의 다른 형태
Main은 커맨드라인 인수를 받을 수 있고 종료 코드를 반환할 수 있습니다. 다음은 모두 올바른 진입점입니다:
static void Main()
static void Main(string[] args)
static int Main()
static int Main(string[] args)
static async Task Main() // C# 7.1 and later
static async Task<int> Main(string[] args) // C# 7.1 and later
반환한 int는 프로세스 종료 코드가 되며, 스크립트와 CI 시스템은 이 값을 읽어 프로그램이 성공했는지 판단합니다(관례상 0이 성공입니다).
출력:
Got 0 argument(s)
dotnet run -- apples pears로 실행하면 args에 "apples"와 "pears"가 들어갑니다. --는 내 프로그램에 줄 인수와 dotnet 도구에 줄 인수를 구분합니다.
주석
C#에는 세 종류의 주석이 있습니다. 컴파일러는 모두 무시합니다.
// A single-line comment runs to the end of the line.
/* A block comment
can span several lines. */
/// <summary>
/// An XML documentation comment. Editors show it as the tooltip for the method.
/// </summary>
static decimal ApplyDiscount(decimal price) => price * 0.9m;
코드 안의 메모에는 //를 씁니다. /// 주석은 타입과 public 멤버에 붙이며, IDE는 호출 위에 마우스를 올리면 이를 표시하고, 컴파일러는 문서화 도구용 XML 파일로 내보낼 수 있습니다.
dotnet으로 프로젝트 만들고 실행하기
내 컴퓨터에서는 dotnet.microsoft.com에서 .NET SDK를 설치한 뒤 다음을 실행합니다:
dotnet new console -o HelloApp
cd HelloApp
dotnet run
Hello, World!
dotnet new console은 두 파일을 만듭니다. HelloApp.csproj(프로젝트 파일: 대상 프레임워크, 설정, 패키지 참조)와 Program.cs입니다. dotnet run은 프로젝트를 컴파일하고 실행합니다. dotnet build는 실행하지 않고 컴파일만 하며 결과물을 bin/Debug/net8.0/에 씁니다(폴더 이름은 대상 프레임워크를 따릅니다).
최상위 문(C# 9 이상)
생성된 Program.cs를 열면 이것 말고는 아무것도 없습니다:
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
이것이 C# 9 기능인 최상위 문 프로그램입니다. 컴파일러가 문장 주위에 Program 클래스와 Main 메서드를 생성합니다. using System;도 없는데, .NET 6 이상 프로젝트는 암시적 using을 켜 두기 때문입니다. System, System.IO, System.Linq, System.Collections.Generic 같은 자주 쓰는 네임스페이스가 프로젝트 전체에 가져와집니다.
최상위 문 프로그램에서도 args를 읽고, await를 쓰고, 종료 코드를 return할 수 있습니다:
// C# 9 and later: the whole Program.cs
Console.Write("Name: ");
string? name = Console.ReadLine();
Console.WriteLine($"Hello, {name}! You passed {args.Length} arguments.");
return 0;
프로젝트당 한 파일만 최상위 문을 가질 수 있고, 타입(클래스, 레코드)은 그 뒤에 와야 합니다. string? 표기는 nullable 참조 형식(C# 8)이며, ReadLine이 null을 반환할 수 있어서 붙어 있습니다. 이 페이지 예제에서 쓰는 명시적인 class Program 형태도 같은 의미이고 예전 코드와 대부분의 Unity 스크립트에서 보게 되므로, 두 형태를 모두 읽을 수 있으면 좋습니다. 새 프로젝트에서 명시적인 형태를 원하면 dotnet new console에 --use-program-main을 넘기세요.
처음 만나게 되는 오류
- CS1002: ; expected. 문장에 세미콜론이 빠졌습니다. 오류는 세미콜론이 빠진 줄의 끝에서 보고됩니다.
- CS0103: The name 'console' does not exist in the current context. 대소문자가 틀렸거나, 암시적 using이 없는 프로젝트에서
using System;이 빠졌습니다. - CS5001: Program does not contain a static 'Main' method suitable for an entry point.
Main의 철자가 틀렸거나,static이 아니거나, 지원하지 않는 시그니처입니다. - CS0017: Program has more than one entry point defined. 두 클래스에 각각
Main이 있습니다. 하나만 남기거나.csproj의StartupObject설정으로 하나를 고르세요. - 창이 바로 닫힙니다. 콘솔 앱을 더블클릭으로 실행하면
Main이 반환될 때 창이 닫힙니다. 터미널에서 실행하거나, 테스트하는 동안 끝에Console.ReadKey();를 추가하세요.
자주 묻는 질문
C#에서 Hello World는 어떻게 작성하나요?
파일 맨 위에 using System;을 두고, 클래스의 static void Main() 메서드 안에 Console.WriteLine("Hello, World!");를 넣습니다. .NET 6 이상에서 dotnet new console로 만든 프로젝트라면 최상위 문이 클래스와 Main을 대신 만들어 주므로, 파일 전체가 그 한 줄이어도 됩니다.
C#의 Main 메서드란 무엇인가요?
Main은 진입점, 즉 프로그램이 시작될 때 런타임이 호출하는 메서드입니다. 반드시 static이어야 하고, void나 int(종료 코드)를 반환할 수 있으며, 커맨드라인 인수를 담은 string[] args 매개변수를 받을 수 있습니다. 프로그램에는 정확히 하나만 있어야 합니다.
Console.Write와 Console.WriteLine의 차이는 무엇인가요?
Console.WriteLine은 텍스트 뒤에 줄바꿈을 쓰므로 다음 출력은 새 줄에서 시작합니다. Console.Write는 텍스트만 쓰므로 다음 출력이 같은 줄에 이어집니다. 인수 없이 Console.WriteLine()을 호출하면 빈 줄이 출력됩니다.
C#에서 사용자 입력은 어떻게 받나요?
Console.ReadLine()은 텍스트 한 줄을 읽어 (줄바꿈 없이) string으로 반환하고, 더 이상 입력이 없으면 null을 반환합니다. 숫자가 필요하면 문자열을 변환하세요. int.TryParse(Console.ReadLine(), out int n)는 텍스트가 숫자가 아닐 때 프로그램이 죽는 대신 false를 반환합니다.
커맨드라인에서 C# 프로그램은 어떻게 실행하나요?
.NET SDK를 설치한 뒤 dotnet new console -o HelloApp으로 프로젝트를 만들고, cd HelloApp으로 이동해 dotnet run으로 빌드와 실행을 합니다. dotnet build는 컴파일만 하며 결과물을 bin/Debug/net8.0/(또는 대상 버전 폴더)에 넣습니다.