숏컷 코드
public static class StringExtensions
{
public static bool IsBlank(this string value)
=> string.IsNullOrWhiteSpace(value);
public static string Truncate(this string value, int maxLength)
=> value.Length <= maxLength ? value : value[..maxLength] + "…";
}
// 마치 인스턴스 메서드처럼 호출
bool empty = " ".IsBlank(); // true
string short = "Hello, World!".Truncate(5); // "Hello…"문법
컴파일러가 변환하는 방식
extension method 호출은 문법 설탕입니다. 컴파일러가 정적 메서드 호출로 바꿉니다.
// 작성한 코드
" ".IsBlank();
// 컴파일러가 생성하는 코드
StringExtensions.IsBlank(" ");따라서 extension method는 null 수신자로도 호출될 수 있습니다. 이 점을 이용해 null 안전 유틸리티를 만들 수 있습니다.
public static bool IsNullOrBlank(this string? value)
=> string.IsNullOrWhiteSpace(value);
string? name = null;
name.IsNullOrBlank(); // ✅ NullReferenceException 없음LINQ는 전부 extension method
Where, Select, OrderBy 등은 System.Linq 네임스페이스의 Enumerable 클래스에 정의된 extension method입니다. using System.Linq;를 추가하면 IEnumerable<T>를 구현하는 모든 타입에서 사용할 수 있게 됩니다.
// 이 두 표현은 완전히 동일
var result = numbers.Where(n => n > 0).ToList();
var result = Enumerable.Where(numbers, n => n > 0).ToList();우선순위 규칙
같은 이름의 메서드가 인스턴스 메서드와 extension method 둘 다 있으면, 인스턴스 메서드가 항상 우선합니다. extension method로는 기존 메서드를 재정의할 수 없습니다.
public class Foo
{
public string ToString() => "instance"; // 항상 이쪽이 호출됨
}
public static class FooExtensions
{
public static string ToString(this Foo f) => "extension"; // 무시됨
}체크포인트
| 규칙 | 설명 |
|---|---|
static class 안에 | extension method는 반드시 static class 안에 |
첫 매개변수에 this | 확장 대상 타입 지정 |
using 필요 | 다른 네임스페이스의 extension은 import 필요 |
| null 수신자 가능 | null?.Method() 대신 직접 방어 로직 작성 가능 |
| 인스턴스 메서드 우선 | 재정의 불가, 추가만 가능 |
주의할 점
extension method를 너무 많은 곳에 정의하면 IDE 자동완성 목록이 복잡해지고, "이 메서드가 어디서 왔는지" 추적하기 어려워집니다. 특히 object나 string처럼 범용 타입에 extension을 붙이면 프로젝트 전체에 영향이 퍼집니다.
한 곳에서만 쓰이는 로직을 extension method로 만드는 것은 과설계입니다. 재사용 가능성이 명확하거나, 메서드 체인이 자연스러운 상황에서 도입하는 편이 좋습니다.
참고 링크
1 sources