코딩 · 프로그래밍 언어
C# 기초 입문 튜토리얼
핵심 답변
C#은 Microsoft가 만든 정적 타입 객체지향 언어로, Windows, macOS, Linux에서 동작하는 무료 크로스 플랫폼 런타임 .NET 위에서 실행됩니다. .NET SDK를 설치하고 dotnet new console을 실행한 뒤 dotnet run을 하면 "Hello, World!"가 출력됩니다. 핵심 개념은 클래스와 레코드, List<T>와 Dictionary<K, V> 같은 제네릭 컬렉션, LINQ 쿼리, async/await, 패턴 매칭, 예외 처리입니다.
C#이란 무엇이고 어디에 쓰이는가
C#("씨 샤프"라고 읽음)은 Microsoft에서 아네르스 헤일스베르(Anders Hejlsberg)가 이끄는 팀이 설계해 2002년에 처음 공개했습니다. Ecma(ECMA-334)에서 표준화되었고 .NET과 함께 오픈 소스로 개발됩니다. C#은 웹 API와 웹사이트(ASP.NET Core), Windows 데스크톱 앱, 크로스 플랫폼 모바일·데스크톱 앱(.NET MAUI), 클라우드 서비스, 게임에 쓰입니다. Unity 엔진은 게임 스크립트에 C#을 사용합니다. 문법이 C 계열이라 자바, C++, 자바스크립트 개발자에게도 익숙합니다.
.NET 설치와 Hello, world 실행
dot.net에서 .NET SDK를 내려받고 dotnet --version으로 확인하세요. 콘솔 프로젝트를 만들고 실행합니다.
dotnet new console -o HelloApp
cd HelloApp
dotnet run
# Hello, World!템플릿은 최상위 문(top-level statements)을 사용하는 Program.cs를 만들므로, 작은 프로그램에는 클래스나 Main 메서드가 필요 없습니다.
Console.WriteLine("Hello, World!");변수와 기본 자료형
모든 변수는 정적 타입을 가집니다. var를 쓰면 값을 보고 컴파일러가 타입을 추론합니다. 값 형식(숫자, bool, struct)은 데이터를 직접 저장하고, 참조 형식(string, 클래스, 배열)은 객체를 가리킵니다.
| 타입 | 예시 | 설명 |
|---|---|---|
int | int n = 42; | 32비트 정수 |
long | long big = 10_000_000_000; | 64비트 정수 |
double | double x = 3.14; | 64비트 부동소수점 |
decimal | decimal price = 19.99m; | 10진수 기반, 금액 계산에 적합 |
bool | bool ok = true; | true 또는 false |
char | char c = 'A'; | UTF-16 코드 단위 |
string | string s = "hi"; | 변경 불가능한 텍스트 |
var name = "Ada";
int count = 7;
double avg = count / 2.0;
Console.WriteLine($"{name} has {count} items, avg {avg}"); // Ada has 7 items, avg 3.5
Console.WriteLine(count / 2); // 3 (integer division)
Console.WriteLine(int.Parse("12") + 1); // 13
string? nickname = null; // ? marks a nullable reference
Console.WriteLine(nickname ?? "none"); // none$"..."는 문자열 보간입니다. 새 프로젝트는 null 허용 참조 형식을 활성화하므로, null일 수 있는 값을 검사 없이 쓰면 컴파일러가 경고합니다.
제어 흐름과 메서드
int score = 72;
if (score >= 90) Console.WriteLine("A");
else if (score >= 70) Console.WriteLine("B"); // B
else Console.WriteLine("C");
for (int i = 0; i < 3; i++) Console.Write($"{Square(i)} "); // 0 1 4
Console.WriteLine();
foreach (var fruit in new[] { "apple", "pear" }) Console.WriteLine(fruit);
string day = "SAT";
string kind = day switch
{
"SAT" or "SUN" => "weekend",
_ => "weekday",
};
Console.WriteLine(kind); // weekend
Console.WriteLine(Greet("Lin")); // Hello, Lin!
static int Square(int x) => x * x;
static string Greet(string name, string greeting = "Hello") => $"{greeting}, {name}!";switch 식과 or 패턴은 C# 패턴 매칭의 일부입니다. 메서드에는 기본 매개변수 값, 명명된 인수(Greet(name: "Lin")), =>를 쓰는 식 본문을 사용할 수 있습니다.
클래스, 속성, 레코드
클래스에는 필드, 속성(get과 set 로직을 가진 필드), 메서드가 있습니다. record는 값을 기준으로 동등성을 판단하는 타입으로, 불변 데이터에 적합합니다.
var acc = new Account("Ann");
acc.Deposit(50);
Console.WriteLine($"{acc.Owner}: {acc.Balance}"); // Ann: 50
var p1 = new Point(3, 4);
var p2 = p1 with { Y = 5 }; // copy with one change
Console.WriteLine(p1); // Point { X = 3, Y = 4 }
Console.WriteLine(p1 == new Point(3, 4)); // True
public class Account
{
public string Owner { get; }
public decimal Balance { get; private set; }
public Account(string owner) => Owner = owner;
public void Deposit(decimal amount)
{
if (amount <= 0) throw new ArgumentException("amount must be positive");
Balance += amount;
}
}
public record Point(int X, int Y);형식 선언은 같은 파일에서 최상위 문 뒤에 와야 합니다. 클래스는 단일 상속(class Savings : Account)과 여러 개의 인터페이스를 지원합니다.
컬렉션과 LINQ
System.Collections.Generic의 제네릭 컬렉션은 일상적으로 쓰는 자료구조입니다. LINQ(Language Integrated Query)는 모든 컬렉션에 Where, Select, OrderBy, GroupBy 같은 메서드를 더해 줍니다.
var nums = new List<int> { 3, 1, 2, 5 };
nums.Add(4);
nums.Sort();
Console.WriteLine(string.Join(", ", nums)); // 1, 2, 3, 4, 5
var ages = new Dictionary<string, int> { ["ann"] = 31, ["bob"] = 25 };
ages["cy"] = 40;
if (ages.TryGetValue("bob", out int bobAge)) Console.WriteLine(bobAge); // 25
var evenSquares = nums.Where(n => n % 2 == 0).Select(n => n * n).ToList();
Console.WriteLine(string.Join(" ", evenSquares)); // 4 16
var oldest = ages.OrderByDescending(kv => kv.Value).First();
Console.WriteLine(oldest.Key); // cy그 밖의 흔한 컬렉션으로 중복 없는 항목을 위한 HashSet<T>, Queue<T>, Stack<T>, 그리고 int[] 같은 고정 크기 배열이 있습니다.
대표 기능: async와 await
C#은 이후 많은 언어가 채택한 async/await 모델을 도입했습니다. async 메서드는 Task를 반환하며, 웹 요청이나 파일 읽기처럼 오래 걸리는 작업을 스레드를 막지 않고 await할 수 있습니다.
using System.Net.Http;
using var http = new HttpClient();
var sizes = await Task.WhenAll(
GetLengthAsync(http, "https://example.com"),
GetLengthAsync(http, "https://example.org"));
Console.WriteLine($"downloaded {sizes.Sum()} characters");
static async Task<int> GetLengthAsync(HttpClient http, string url)
{
string html = await http.GetStringAsync(url);
return html.Length;
}Task.WhenAll은 두 요청을 동시에 실행하고 둘 다 끝나기를 기다립니다. using var 선언은 스코프가 끝날 때 HttpClient를 해제합니다.
예외 처리
오류는 예외입니다. 구체적인 타입을 먼저 잡고, 정리 작업에는 finally나 using을 사용하세요. 잘못된 입력이 흔한 경우에는 TryParse 패턴으로 예외를 피할 수 있습니다.
try
{
int age = int.Parse("abc");
}
catch (FormatException ex)
{
Console.WriteLine($"not a number: {ex.Message}");
}
finally
{
Console.WriteLine("done");
}
if (!int.TryParse("41", out int parsed)) parsed = 0;
Console.WriteLine(parsed); // 41작은 완성 프로그램: 단어 빈도 세기
콘솔 프로젝트의 Program.cs를 이 코드로 바꾼 뒤 dotnet run -- notes.txt로 실행하세요.
using System.Text.RegularExpressions;
if (args.Length != 1)
{
Console.Error.WriteLine("usage: dotnet run -- FILE");
return 1;
}
try
{
string text = File.ReadAllText(args[0]).ToLowerInvariant();
var top = Regex.Matches(text, "[a-z']+")
.GroupBy(m => m.Value)
.Select(g => (Word: g.Key, Count: g.Count()))
.OrderByDescending(t => t.Count)
.Take(5);
foreach (var (word, count) in top)
Console.WriteLine($"{count,5} {word}");
return 0;
}
catch (FileNotFoundException)
{
Console.Error.WriteLine($"file not found: {args[0]}");
return 1;
}최상위 문에서는 명령줄 args를 읽고 종료 코드를 반환할 수 있습니다. System.IO, System.Linq, System.Collections.Generic은 새 프로젝트의 암시적 using을 통해 자동으로 임포트됩니다.
초보자가 자주 하는 실수
- 금액에
double을 쓰는 경우. 이진 반올림 오류를 피하려면decimal을 사용하세요. - null 허용 경고를 무시하는 경우. 결국 실행 시점의
NullReferenceException이 됩니다. - 같은 리스트를
foreach로 순회하는 도중에List<T>를 수정하는 경우.InvalidOperationException이 발생합니다. - 오래 실행되는 앱에서 요청마다 새
HttpClient를 만드는 경우. 인스턴스 하나를 재사용하거나IHttpClientFactory를 사용하세요. - LINQ 쿼리가 지연 실행된다는 점을 잊는 경우.
ToList()를 호출하지 않으면 열거할 때마다 쿼리가 다시 실행됩니다.
다음 학습 단계
Microsoft Learn에 언어 둘러보기와 대화형 튜토리얼을 포함한 공식 C# 문서가 있습니다. 그다음 웹 API용 ASP.NET Core, 데이터베이스용 Entity Framework Core, 게임용 Unity를 배우고, 테스트에는 xUnit이나 NUnit을 사용하세요. Visual Studio, C# Dev Kit을 설치한 VS Code, JetBrains Rider가 흔히 쓰는 편집기입니다.
자주 묻는 질문
C#은 Windows 전용인가요?
아닙니다. 현대 .NET은 Windows, macOS, Linux에서 실행되고 C# 앱을 Linux 서버와 컨테이너에 배포할 수 있습니다. WPF와 Windows Forms 같은 일부 데스크톱 UI 프레임워크만 Windows 전용입니다.
C#과 .NET은 무엇이 다른가요?
C#은 프로그래밍 언어입니다. .NET은 C# 코드(그리고 F#과 Visual Basic)를 컴파일하고 실행하는 런타임과 라이브러리입니다.
C#은 자바와 비슷한가요?
네, 여러 면에서 그렇습니다. 둘 다 정적 타입, 가비지 컬렉션, 객체지향 언어이며 C 스타일 문법을 씁니다. C#은 속성, LINQ, async/await, 값 형식 구조체, 레코드 같은 기능을 더했습니다.
C#은 게임 개발에 좋은가요?
네. 가장 널리 쓰이는 게임 엔진 중 하나인 Unity가 게임 스크립트에 C#을 사용하고, Godot 엔진도 C#을 지원합니다.