getter 만 사용하는 자동화 된 속성, 설정할 수있는 이유는 무엇입니까?


96

자동화 된 속성을 만들었습니다.

public int Foo { get; } 

이것은 게터 전용입니다. 하지만 생성자를 만들 때 값을 변경할 수 있습니다.

public MyClass(string name)
{
    Foo = 5;
}

이것이 get-only인데 왜 가능합니까?


실제로 세터를 사용하지 않습니다 (세터가 없기 때문에). 기본 필드를 직접 설정합니다 (우리에게 숨겨져 있으므로 속성 이름을 사용해야합니다).
Dennis_E

14
초기화 / 설정할 수 없는 경우 속성의 용도는 무엇입니까 ? Yacoub Massad는 완벽하게 응답 한
Vikhram

답변:


123

이것은 Mark의 MSDN 매거진 기사 'C # : The New and Improved C # 6.0'에 설명 된대로 "읽기 전용 속성에 대한 자동 속성 이니셜 라이저"라고도하는 새로운 C # 6 기능인 "게터 전용 자동 속성"입니다 . MichaelisC # 6.0 초안 언어 사양 .

읽기 전용 필드의 setter는 생성자에서만 액세스 할 수 있으며, 다른 모든 시나리오에서 필드는 여전히 읽기 전용이며 이전처럼 동작합니다.

이는 입력해야하는 코드의 양을 줄이고 값을 보유하기 위해 비공개 모듈 수준 변수를 명시 적으로 선언 할 필요를 없애기위한 편리한 구문입니다.

이 기능은 C # 3에 자동 구현 된 속성이 도입 된 이후로 변경 가능한 속성 (게터 및 세터가있는 속성)이 변경 불가능한 속성 (게터 만있는 속성)보다 더 빠르게 작성 되었기 때문에 중요한 것으로 간주되었습니다. 일반적으로 읽기 전용 속성에 필요한 지원 필드에 대한 코드를 입력 할 필요가 없도록 변경 가능한 속성을 사용하려는 유혹을받습니다. Microsoft C # 프로그래밍 가이드관련 섹션 에서 자동 구현 속성에 대한 자세한 설명이 있습니다 .

Sean Sexton의이 블로그 게시물 '# 1,207 – C # 6.0 – 읽기 전용 속성에 대한 자동 속성 초기화 프로그램' 에는 다음과 같은 좋은 설명과 예가 있습니다.

C # 6.0 이전에는 읽기 전용 (변경 불가능) 속성이 필요한 경우 일반적으로 아래와 같이 생성자에서 초기화되는 읽기 전용 지원 필드를 사용합니다.

public class Dog 
{
    public string Name { get; set; }

    // DogCreationTime is immutable
    private readonly DateTime creTime;
    public DateTime DogCreationTime 
    {
        get { return creTime; }
    }

    public Dog(string name)
    {
        Name = name;
        creTime = DateTime.Now;
    }
}

C # 6.0에서는 자동 구현 속성을 사용하여 읽기 전용 속성을 구현할 수 있습니다. 이 작업은 자동 속성 이니셜 라이저를 사용하여 수행합니다. 결과는 명시 적으로 지원 필드를 선언해야하는 위의 예보다 훨씬 더 깔끔합니다.

public class Dog
{
    public string Name { get; set; }

    // DogCreationTime is immutable
    public DateTime DogCreationTime { get; } = DateTime.Now;

    public Dog(string name)
    {
        Name = name;
    }
}

자세한 내용은 GitHub의 dotnet Roslyn 저장소 에서도 확인할 수 있습니다 .

이제 자동 속성을 setter없이 선언 할 수 있습니다.

getter 전용 자동 속성의 지원 필드는 암시 적으로 읽기 전용으로 선언됩니다 (반영 목적으로 만 중요 함). 위 예제와 같이 속성의 이니셜 라이저를 통해 초기화 할 수 있습니다. 또한 선언 유형의 생성자 본문에서 getter 전용 속성을 할당 할 수 있으므로 값이 기본 필드에 직접 할당됩니다.

이것은 타입을보다 간결하게 표현하는 것에 관한 것이지만 변경 가능한 타입과 변경 불가능한 타입 사이의 언어에서 중요한 차이를 제거합니다. 그것은 훌륭했습니다. 이제 getter 전용 자동 속성을 사용하여 경쟁 영역이 변경 가능과 불변 사이에서 평준화되었습니다.

과에서 C # 6.0 초안 언어 사양 (주의 : 지금까지 마이크로 소프트 등에 관한 한 언어 사양은 최종 만은 아직 EMCA / ISO 표준으로 승인을 따라서 '초안') :

자동 구현 속성

자동으로 구현 된 속성 (또는 줄여서 auto-property)은 세미콜론 전용 접근 자 본문이있는 비추 상 비추 상 속성입니다. 자동 속성에는 get 접근자가 있어야하며 선택적으로 set 접근자를 가질 수 있습니다.

속성이 자동으로 구현 된 속성으로 지정되면 숨겨진 지원 필드가 속성에 자동으로 사용 가능하며 접근자는 해당 지원 필드에서 읽고 쓰기 위해 구현됩니다. 자동 속성에 설정된 접근자가 없으면 지원 필드는 읽기 전용 (읽기 전용 필드)으로 간주됩니다. 읽기 전용 필드와 마찬가지로 getter 전용 자동 속성을 포함하는 클래스의 생성자 본문에 할당 할 수도 있습니다. 이러한 할당은 속성의 읽기 전용 지원 필드에 직접 할당됩니다.

auto-property는 선택적으로 property_initializer를 가질 수 있으며, 이는 variable_initializer (Variable initializers)로 지원 필드에 직접 적용됩니다.


1
이것은 어리석은 디자인입니다. 속성이 읽기 전용으로 간주되는 위치에 설정된 경우 컴파일 타임 오류 여야합니다.
Shiv

나에게 이상한 점은 CS0200 C# Property or indexer cannot be assigned to -- it is read only일반 속성을 사용할 때 말하는 컴파일러 오류가 여전히 있다는 것 입니다. "Getter 전용 자동 속성"은 읽기 전용으로 간주됩니까?
Kyle Delaney

24

이것은 C # 6의 새로운 기능입니다. 읽기 전용 속성을 만들고 생성자 (또는 선언 할 때 인라인)에서 해당 값을 초기화 할 수 .

생성자 외부에서이 속성의 값을 변경하려고하면 컴파일 오류가 발생합니다.

값을 초기화하면 (인라인 또는 생성자 내부) 값을 변경할 수 없다는 점에서 읽기 전용입니다.


그래서, 설명은 무엇입니까? getter의 정의는 무엇입니까?
Noam B.

16

생성자 (또는 자동 속성 이니셜 라이저)에서 읽기 전용 속성을 초기화 할 수없는 경우 항상 해당 유형의 기본값 (숫자의 경우 0, 참조 유형의 경우 null)을 반환하므로 쓸모가 없습니다. ). 모든 C # 버전의 읽기 전용 필드에 동일한 의미가 적용됩니다 .

생성자에서 초기화 할 수없는 진정한 getter 전용 속성을 정의하려면 정의의 일부로 반환되는 내용을 지정해야합니다.

public int Foo { get { return 5; } }

또는 C # 6에서 더 간결하게 설명합니다.

public int Foo => 5;

완전히 사실은 아니지만 읽기 전용 속성은 코드에서 일부 조건을 캡슐화하는 데 매우 유용합니다. 문과 거의 모든 코드가 다른 속성이나 조건을 평가하고 적절한 값 당신이 재산 읽을 때마다 반환하는 경우 당신은 쓸 수 있습니다
sebagomez

3
@sebagomez : 내가 당신의 요점을 이해하고 있는지 잘 모르겠습니다. 제 예에서 보여준 것이 아닌가요?
Douglas

5

"읽기 전용 자동 구현 속성"

우선 속성이

public string FirstName { get; }

"읽기 전용 자동 구현 속성"이라고합니다.

이를 확인하기 위해 Visual Studio로 위의 코드를 실행하고 확인할 수 있습니다. 언어 버전을 C # 6.0에서 C # 5.0으로 변경하면 컴파일러에서 다음과 같은 예외가 발생 합니다. C # 5에서는 '자동으로 구현 된 읽기 전용 속성'기능을 사용할 수 없습니다. 언어 버전 6 이상을 사용하세요.

C # 언어 버전을 변경하려면 여기를 방문 하십시오.

이제 두 번째 질문에갑니다

“이것은 게터 전용입니다. 하지만 생성자를 만들 때 값을 변경할 수 있습니다.”

Microsoft는 읽기 전용 논리에 "읽기 전용 자동 구현 속성"을 도입했습니다. "readonly"키워드는 C # 1.0에서 사용할 수 있습니다. 우리는 "읽기 전용"필드에 수정하고 해당 필드와 같은 키워드에 할당 할 수 있습니다 사용하십시오 2 가지 방법 중 하나를 선언 할 때 또는 같은 클래스의 생성자에서.

같은 방식으로 "읽기 전용 자동 구현 속성"값을 두 가지 방법으로 할당 할 수 있습니다.

Way1 (선언 당시) :

public string FirstName { get; } = "Banketeshvar";

Way2 (같은 클래스의 생성자에서)

Person()
{
 FirstName  = "Banketeshvar";
}

순수 읽기 전용 속성

순전히 읽기 전용 속성을 찾고 있다면 이것을 찾으십시오.

public string FullName => "Manish Sharma";

이제 생성자에서 "FullName"속성 값을 할당 할 수 없습니다. 그렇게하려고하면 다음 예외가 발생합니다.

"속성 또는 인덱서 'Person.FullName'을 (를) 할당 할 수 없습니다. 읽기 전용입니다."


2
FullName => "foo bar"는 매번 평가됩니다.
juFo

4

자동 속성 기능은 C # 3.0 릴리스 중에 언어에 추가되었습니다. 지원 필드없이 속성을 정의 할 수 있지만 이러한 자동 속성을 기본값이 아닌 값으로 초기화하려면 생성자를 사용해야합니다. C # 6.0에는 아래와 같은 생성자없이 이러한 속성을 초기화 할 수있는 자동 속성 이니셜 라이저라는 새로운 기능이 도입되었습니다.

이전에는 자동 속성을 사용하여 객체를 만들고 자동 속성을 아래와 같이 기본값이 아닌 값으로 초기화하려면 생성자가 필요합니다.

public class MyClass
{
    public int Foo { get; }

    public Foo(int foo)
    {
        Foo = foo;
    }
}

이제 C # 6.0에서 자동 속성과 함께 이니셜 라이저를 사용하는 기능은 명시 적 생성자 코드가 필요하지 않음을 의미합니다.

public string Foo { get; } = "SomeString";

public List<string> Genres { get; } = new List<string> { "Comedy", "Drama" };

여기에서 자세한 정보를 찾을 수 있습니다.


1

선언 된 변수는 readonly생성자 내에서 작성할 수 있지만 속성을 따르는 언어에서는 생성자가 반환 한 후에 수정할 수 없습니다. 해당 한정자는 생성자 매개 변수에 따라 값이 달라지는 필드 (생성자가 시작되기 전에 초기화 할 수 없음)가 종종 필요하지만 생성자가 반환 된 후에 변경할 필요가 없기 때문에 언어 기능으로 제공되었지만 필드로 노출 된 변수에만 사용할 수 있습니다. 의미론readonly정규화 된 필드 클래스가 멤버 (불변의 멤버도 포함)를 필드가 아닌 속성으로 노출하는 것이 더 낫다는 점을 제외하면 많은 경우 공용 멤버에게 완벽했습니다.

클래스가 일반 필드처럼 쉽게 변경 가능한 속성을 노출 할 수 있도록 읽기-쓰기 자동 속성이 존재하는 것처럼, 클래스가 readonly정규화 된 필드 만큼 쉽게 변경할 수없는 속성을 노출 할 수 있도록 읽기 전용 자동 속성이 존재 합니다. readonly-qualified 필드가 생성자에서 작성 될 수있는 것처럼 get-only 속성도 마찬가지입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.