Quick Reference
메서드는 반환 타입 이름(매개변수) 본문으로 선언합니다. 매개변수는 없을 수도 있고, 반환 타입은 void 또는 값 타입입니다. 호출자는 optional·named·params 규칙에 따라 인자를 생략하거나 이름으로 지정할 수 있습니다.
void Log() => Console.WriteLine("saved"); // 매개변수·반환값 없음
int GetCount() => 3; // 매개변수 없음, 값 반환
int Add(int left, int right) => left + right; // 필수 매개변수
void Create(string name, int level = 1) { }
int Sum(params int[] values) => values.Sum();
Log();
int count = GetCount();
Create("Mina", level: 5);
int total = Sum(); // 0개
total = Sum(1, 2, 3); // 개별 인자
total = Sum([1, 2, 3]); // 배열- 입력을 받지 않으면 빈
(), 반환하지 않으면void를 씁니다. - 기본 argument는 optional parameter 뒤에만 둘 수 있고, named argument는 순서의 의미를 드러낼 때 씁니다.
params는 마지막 매개변수 하나에만 붙입니다.- 호출 모양이 달라지는
ref/out/in은 ref, out, in에서 다룹니다.
선언과 반환
블록 본문은 여러 문과 조기 return을, 식 본문 =>는 하나의 식을 표현할 때 적합합니다. non-void 메서드는 모든 정상 종료 경로에서 반환값을 제공해야 합니다.
static string Classify(int score)
{
if (score < 0) throw new ArgumentOutOfRangeException(nameof(score));
return score >= 60 ? "pass" : "fail";
}
static bool IsAdult(int age) => age >= 18;local function은 한 메서드 안에서만 쓰는 이름 있는 보조 로직입니다. 외부 API 표면을 늘리지 않고, lambda보다 명시적인 parameter·return·generic contract가 필요할 때 선택합니다.
static int SumPositive(IEnumerable<int> values)
{
return values.Where(IsPositive).Sum();
static bool IsPositive(int value) => value > 0;
}static local function은 바깥 지역 변수를 캡처할 수 없으므로, 의도하지 않은 closure를 막고 입력을 signature에 드러냅니다.
Optional, named, params, overload
static void Create(string name, int level = 1, bool isAdmin = false) { }
Create("Mina");
Create("Jin", level: 5);
Create(name: "Sol", isAdmin: true, level: 3);optional argument의 기본값은 호출하는 assembly에 컴파일되어 들어갑니다. library가 level = 1을 2로 바꿔도 이미 빌드한 caller는 다시 컴파일하기 전까지 이전 값을 보낼 수 있습니다. public API에서 의미가 바뀔 수 있는 default는 overload나 options type으로 분리합니다.
overload는 이름은 같아도 parameter type, 개수, 전달 방식이 달라야 합니다. 반환 타입만 다른 overload는 만들 수 없으며, 숫자 변환·optional·params가 함께 있으면 compiler가 더 적합한 후보를 고르는 규칙이 복잡해집니다.
static int Add(int left, int right) => left + right;
static double Add(double left, double right) => left + right;
static int Add(int left, int right, int extra) => left + right + extra;API를 나누는 기준
parameter가 늘어날수록 호출자가 순서·의미·기본값을 기억해야 합니다. 서로 항상 함께 움직이는 값을 options class/record로 묶고, 하나의 method가 query와 state mutation을 동시에 한다면 둘을 나눕니다.
public sealed record CreateUserOptions(string Name, int Level, bool IsAdmin);
static User CreateUser(CreateUserOptions options) => new(options.Name, options.Level);method가 I/O, 긴 계산, 예외 발생, allocation처럼 관찰 가능한 비용을 갖는다면 property보다 method로 표현합니다. property contract는 빠르고 반복해 읽어도 놀랍지 않다는 기대를 갖습니다.
자주 틀리는 부분
params와 optional parameter를 여러 overload에 섞으면 호출 하나가 어떤 overload를 고르는지 읽기 어렵습니다. compiler가 고르도록 남기기보다 이름을 나누거나 호출 예제를 테스트하세요.
매개변수 없는 메서드도 상태를 바꾸거나 예외를 던질 수 있습니다. Get...처럼 읽기 전용으로 보이는 이름에는 mutation이나 네트워크 호출을 숨기지 않는 편이 좋습니다.
참고 링크
2 sources