14.0 · 버전 이력

C# 14.0

밖에서 형식을 확장하는 길이 늘었습니다.

2025.11 .NET 10
한눈에

무엇이 더해졌나

C# 14.0은 .NET 10과 함께 2025년 11월에 나왔습니다. 손댈 수 없는 형식을 밖에서 확장하는 길이 늘고, 속성을 작성할 때 되풀이하던 것이 줄었습니다.

  • 확장 멤버 — 메서드만 되던 확장에 속성과 정적 멤버가 더해졌습니다.
  • field 키워드 — 속성이 사용하는 저장 공간을 이름으로 부릅니다.
  • null 조건 대입?. 를 대입의 왼쪽에도 사용합니다.
  • Span 변환 — 배열을 Span 으로 보는 자리가 늘었습니다.
확장 멤버

확장이 메서드에서 멈추지 않습니다

남이 만든 형식에 기능을 더하는 방법은 확장 메서드뿐이었습니다. 그래서 값을 돌려주기만 하는 것도 메서드로 적어 괄호를 붙여야 했고, 정적 멤버는 아예 추가할 수 없었습니다. 이제 extension 묶음 안에 속성과 정적 멤버를 함께 둡니다.

C# 13 까지
static class Texts {
    public static bool IsBlank(
        this string s) =>
        string.IsNullOrWhiteSpace(s);
}

// 부르는 쪽
if (name.IsBlank()) { }
C# 14 부터
static class Texts {
    extension(string s) {
        public bool IsBlank =>
            string.IsNullOrWhiteSpace(s);
    }
}

// 부르는 쪽
if (name.IsBlank) { }

형식 자체에 붙이는 정적 멤버도 둘 수 있습니다. 받을 대상 없이 형식 이름만 적습니다.

static class Texts {
    extension(string) {
        public static string Nbsp => "\u00A0";
    }
}

Console.WriteLine(string.Nbsp.Length);   // 1

this 를 붙이는 기존 확장 메서드도 그대로 동작합니다. 새 방식이 그것을 대신하는 것이지 없애는 것이 아닙니다.

field 키워드

저장 공간을 이름으로 부릅니다

속성에서 값을 조금이라도 손보려면 자동 속성을 포기하고 필드를 따로 선언해야 했습니다. 실제로 하는 일은 한 줄인데 필드 하나와 접근자 두 개가 함께 늘어났습니다. 이제 field 로 그 저장 공간을 직접 부릅니다.

C# 13 까지
private string _name = "";

public string Name {
    get => _name;
    set => _name = value.Trim();
}
C# 14 부터
public string Name {
    get => field;
    set => field = value.Trim();
} = "";

필드가 사라지므로 그 이름을 다른 곳에서 잘못 사용할 일도 없어집니다. 이미 field 라는 이름의 변수가 있는 코드에서는 @field 로 적어 구분합니다.

C# 2.2 필드, 프로퍼티, 접근 제한자 에서 속성이 무엇을 감추는지 다룹니다.

그 밖에

null 조건 대입과 Span 변환

?. 는 읽을 때만 사용할 수 있었습니다. 값을 넣을 때는 if 로 한 번 감싸야 했습니다. 이제 대입의 왼쪽에도 사용합니다. 대상이 null 이면 오른쪽은 계산조차 하지 않습니다.

C# 13 까지
if (user is not null)
    user.Name = "홍길동";
C# 14 부터
user?.Name = "홍길동";

배열을 Span 으로 받는 매개 변수에 그냥 넘기는 것은 전부터 됐습니다. 이 판에서 달라진 것은 언어가 그 변환을 직접 안다는 점입니다. 그래서 확장 메서드의 수신자와 제네릭 추론에서도 같은 변환이 쓰입니다.

static int Len(this ReadOnlySpan<int> s) => s.Length;
static int Count<T>(ReadOnlySpan<T> s) => s.Length;

int[] numbers = [1, 2, 3];

numbers.Len();     // C# 13 까지는 되지 않았습니다
Count(numbers);    // C# 13 까지는 T 를 알아내지 못했습니다
배경
  • 이 판이 겨눈 것은 손댈 수 없는 형식을 밖에서 다루는 것입니다.
  • 확장 멤버는 메서드로만 가능하던 것을 속성과 정적 멤버까지 확장했습니다.
  • field속성 하나에 딸려 오던 필드를 없앴습니다.