getter 만 사용하는 자동화 된 속성, 설정할 수있는 이유는 무엇입니까?
자동화 된 속성을 만들었습니다.
public int Foo { get; }
이것은 게터 전용입니다. 하지만 생성자를 만들 때 값을 변경할 수 있습니다.
public MyClass(string name)
{
Foo = 5;
}
이것이 get-only인데 왜 가능합니까?
이것은 Mark의 MSDN 매거진 기사 'C # : The New and Improved C # 6.0'에 설명 된대로 "읽기 전용 속성에 대한 자동 속성 이니셜 라이저"라고도하는 새로운 C # 6 기능인 "게터 전용 자동 속성"입니다 . Michaelis 및 C # 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없이 선언 할 수 있습니다.
The backing field of a getter-only auto-property is implicitly declared as readonly (though this matters only for reflection purposes). It can be initialized through an initializer on the property as in the example above. Also, a getter-only property can be assigned to in the declaring type’s constructor body, which causes the value to be assigned directly to the underlying field:
This is about expressing types more concisely, but note that it also removes an important difference in the language between mutable and immutable types: auto-properties were a shorthand available only if you were willing to make your class mutable, and so the temptation to default to that was great. Now, with getter-only auto-properties, the playing field has been leveled between mutable and immutable.
and in the C# 6.0 draft Language Specification (NB: The language specification is final as far as Microsoft are concerned, but it is yet to be approved as a EMCA/ISO standard, hence the 'draft'):
Automatically implemented properties
An automatically implemented property (or auto-property for short), is a non-abstract non-extern property with semicolon-only accessor bodies. Auto-properties must have a get accessor and can optionally have a set accessor.
When a property is specified as an automatically implemented property, a hidden backing field is automatically available for the property, and the accessors are implemented to read from and write to that backing field. If the auto-property has no set accessor, the backing field is considered readonly (Readonly fields). Just like a readonly field, a getter-only auto-property can also be assigned to in the body of a constructor of the enclosing class. Such an assignment assigns directly to the readonly backing field of the property.
An auto-property may optionally have a property_initializer, which is applied directly to the backing field as a variable_initializer (Variable initializers).
This is a new feature in C#6 that allows you to create read-only properties and initialize their values from the constructor (or inline when you declare them).
If you try to change the value of this property outside the constructor, it would give you a compile error.
It is read-only in the sense that once you initialize its value (inline or inside the constructor), you cannot change its value.
If it were not possible to initialize the read-only property from the constructor (or an auto-property initializer), then it would be useless, since it would always return the default value for its type (0 for numerics, null for reference types). The same semantics applied to readonly fields in all C# versions.
To define a true getter-only property (that cannot be initialized from the constructor), you need to specify what it returns as part of the definition:
public int Foo { get { return 5; } }
Or, more concisely in C# 6:
public int Foo => 5;
“readonly automatically implemented properties”
First of all I want to clarify that the property like
public string FirstName { get; }
Is known as “readonly automatically implemented properties”
To verify this you can run & check the above code with Visual Studio. If you change the language version from C#6.0 to C#5.0 then compiler will throw the following exception Feature 'readonly automatically implemented properties' is not available in C# 5. Please use language version 6 or greater.
to change C# language version visit here
Now I am coming to your second question
“This is getter only. But when I build a constructor, I can change the value”
Microsoft introduces the “readonly automatically implemented properties” on the logic of read only. As we know that the keyword “readonly” is available from C#1.0. we use “readonly” keyword as modifier on a field and that field can be assigned in 2 ways either at the time of declaration or in a constructor in the same class.
In the same way value of “readonly automatically implemented properties” can be assigned in 2 ways
Way1 (at the time of declaration):
public string FirstName { get; } = "Banketeshvar";
Way2 (in a constructor in the same class)
Person()
{
FirstName = "Banketeshvar";
}
Purely ReadOnly Property
If you are looking for purely Readonly property then go for this
public string FullName => "Manish Sharma";
now you cannot assign value of “FullName” propery from constructor. If you try to do that it will throw the following exceptions
“Property or indexer 'Person.FullName' cannot be assigned to -- it is read only”
Auto property feature was added to the language during C# 3.0 release. It allows you to define a property without any backing field, however you still need to use constructor to initialize these auto properties to non-default value. C# 6.0 introduces a new feature called auto property initializer which allows you to initialize these properties without a constructor like Below:
Previously, a constructor is required if you want to create objects using an auto-property and initialize an auto-property to a non-default value like below:
public class MyClass
{
public int Foo { get; }
public Foo(int foo)
{
Foo = foo;
}
}
Now in C# 6.0, the ability to use an initializer with the auto-property means no explicit constructor code is required.
public string Foo { get; } = "SomeString";
public List<string> Genres { get; } = new List<string> { "Comedy", "Drama" };
You can find more information on this here
A variable declared readonly
can be written within a constructor, but in languages which honor the attribute, cannot be modified after the constructor returns. That qualifier was provided as a language feature because it is often necessary for fields whose values will vary based upon constructor parameters (meaning they can't be initialized before the constructor starts) but won't have to change after constructors return, but it was only usable for variables exposed as fields. The semantics of readonly
-qualified fields would in many cases have been perfect for public members except that it's often better for classes to expose members--even immutable ones--as properties rather than fields.
Just as read-write auto-properties exist to allow classes to expose mutable properties as easily as ordinary fields, read-only auto-properties exist to allow classes to expose immutable properties as easily as readonly
-qualified fields. Just as readonly
-qualified fields can be written in a constructor, so too with get-only properties.
참고URL : https://stackoverflow.com/questions/34743533/automated-property-with-getter-only-can-be-set-why
'developer tip' 카테고리의 다른 글
Windows 용 Git Bash에서 별칭을 설정하는 방법은 무엇입니까? (0) | 2020.09.16 |
---|---|
출구와 귀국의 차이점은 무엇입니까? (0) | 2020.09.16 |
여러 RE 엔진을 사용하여 정규식을 테스트하려면 어떻게해야합니까? (0) | 2020.09.16 |
동기화되지 않은 명령 (0) | 2020.09.16 |
가상 메모리와 실제 메모리의 차이점은 무엇입니까? (0) | 2020.09.16 |