`set` 키워드: 프로퍼티 접근자

set 키워드: 프로퍼티 접근자

프로퍼티나 인덱서에 값을 할당하는 일은 어떻게 구현할까요? 그 역할을 맡은 게 바로 set 키워드예요. set 키워드는 프로퍼티 또는 인덱서 요소에 값을 대입하는 접근자(accessor) 메서드를 정의해요. 더 자세한 내용과 예시는 프로퍼티, 자동 구현 프로퍼티, 인덱서에서 다룰게요.

출처: The set keyword (C# Reference)

본문

프로퍼티의 getset 접근자가 하는 일이 비공개 지원 필드(private backing field)에 값을 넣고 빼는 것뿐이라면, 그런 단순한 경우에는 직접 손으로 쓸 필요가 없어요. 자동 구현 프로퍼티(automatically implemented property)를 쓰면 컴파일러가 대신 만들어 줘요. 아래 예시는 Hours를 자동 구현 프로퍼티로 구현한 모습이에요.

class TimePeriod3
{
    public double Hours { get; set; }
}

[!IMPORTANT] 자동 구현 프로퍼티는 인터페이스 프로퍼티 선언이나 부분 프로퍼티의 구현 선언에는 쓸 수 없어요. 컴파일러는 자동 구현 프로퍼티 형태와 일치하는 구문을 구현 선언이 아니라 선언 선언으로 해석해요.

그런데 실제로는 접근자 둘 중 하나만 직접 구현해야 할 때도 있어요. 이런 경우 C# 14에서 추가된 field 키워드로 필드 지원 프로퍼티(field backed property)를 선언하면 돼요. 한쪽 접근자는 컴파일러가 만들어 주고, 다른 쪽은 직접 쓰되, field 키워드로 컴파일러가 합성한 지원 필드에 접근하는 방식이에요.

class TimePeriod4
{
    public double Hours {
        get;
        set => field = (value >= 0)
            ? value
            : throw new ArgumentOutOfRangeException(nameof(value), "The value must not be negative");
    }
}

set 접근자는 대부분 앞 예시처럼 값을 하나 대입하는 단일 문장으로 끝나요. 그렇다면 식 본문 멤버(expression-bodied member)로도 구현할 수 있어요. 아래 예시는 getset 접근자를 둘 다 식 본문 멤버로 작성한 모습이에요.

class TimePeriod2
{
    private double _seconds;

    public double Seconds
    {
        get => _seconds;
        set => _seconds = value;
    }
}

마지막 예시는 Seconds라는 프로퍼티에 get 접근자와 set 접근자를 모두 정의해요. 프로퍼티 값을 받쳐 주는 비공개 필드로는 _seconds를 쓰죠. 여기서 set 접근자가 하는 일을 눈여겨볼게요. 대입되는 value가 음수면 예외를 던져서 잘못된 값을 걸러내고, 정상 범위 값일 때만 _seconds에 저장해요.

class TimePeriod
{
    private double _seconds;

    public double Seconds
    {
        get { return _seconds; }
        set
        {
            if (value < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(value), "The value of the time period must be non-negative.");
            }
            _seconds = value;
        }
    }
}

더 알아보기