레코드에서 속성을 두 번 정의

Dec 02 2020

C # 9에서는 기본 생성자와 본문 모두에서 레코드에 동일한 이름의 속성을 정의 할 수 있습니다.

record Cat(int PawCount)
{
    public int PawCount { get; init; }
}

이 코드는 오류없이 컴파일됩니다.

이러한 레코드의 인스턴스를 초기화 할 때 생성자에 제공된 값은 완전히 무시됩니다.

Console.WriteLine(new Cat(4));
Console.WriteLine(new Cat(4) { PawCount = 1 });

인쇄물

Cat { PawCount = 0 }
Cat { PawCount = 1 }

이 동작이 정확합니까 아니면 버그입니까? 정확하다면 어떤 경우에 유용합니까?

컴파일러가 'The type Catalready contains a definition for PawCount' 와 같은 오류로이 코드를 거부 하거나 생성자와 본문의 속성을 동일하게 고려하여 생성자에서 초기화를 수행 할 것으로 예상했습니다 . 후자의 변형은 본문에서 위치 레코드의 모든 속성을 다시 작성하지 않고도 사용자 지정 getter 및 / 또는 이니셜 라이저를 속성에 제공하는 데 유용 할 수 있습니다.

실제 행동은 나에게 의미가 없습니다.

답변

9 YairHalberstadt Dec 02 2020 at 22:10

이를 수행하는 올바른 방법은 다음과 같습니다.

record Cat(int PawCount)
{
    public int PawCount { get; init; } = PawCount;
}

예를 들어 유효성 검사를 수행 할 수 있으므로 유용합니다.

record Cat(int PawCount)
{
    private int _pawCount;
    public int PawCount {
        get => _pawCount;
        init => _pawCount = value < 0 ? throw new ArgumentException() : value; 
    } = PawCount;
}

이에 대한 사양은 다음과 같습니다. https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/records.md#members-of-a-record-type

"일치하는"서명이있는 구성원이 레코드 본문에 선언되거나 "일치하는"서명이있는 액세스 가능한 구체적인 비가 상 구성원이 상속되지 않는 한 구성원이 합성됩니다. 두 구성원이 동일한 서명을 가지고 있거나 상속 시나리오에서 "숨겨진"것으로 간주되는 경우 일치하는 것으로 간주됩니다.

따라서 매개 변수와 이름이 같은 속성이 이미 존재하기 때문에 컴파일러는 PawCount속성을 합성하지 않으므로 직접 명시 적으로 사용하지 않는 한 매개 변수를 자동으로 무시합니다.