Я створив автоматизовану властивість:
public int Foo { get; }
Це лише геттер. Але коли я будую конструктор, я можу змінити значення:
public MyClass(string name)
{
Foo = 5;
}
Чому це можливо, хоча це лише для отримання?
Я створив автоматизовану властивість:
public int Foo { get; }
Це лише геттер. Але коли я будую конструктор, я можу змінити значення:
public MyClass(string name)
{
Foo = 5;
}
Чому це можливо, хоча це лише для отримання?
Відповіді:
Це нова функція C # 6, "Автоматичні властивості лише для отримання", також відома як "Ініціалізатори властивостей для властивостей лише для читання", як обговорюється в цій статті журналу MSDN "C #: Новий та вдосконалений C # 6.0" Марка Michaelis та у проекті мовної специфікації C # 6.0 .
Установник поля лише для читання доступний лише в конструкторі, у всіх інших сценаріях поле все ще доступне лише для читання і поводиться як раніше.
Це зручний синтаксис для зменшення кількості коду, який потрібно ввести, і для усунення необхідності явно оголошувати змінну рівня приватного модуля для зберігання значення.
Ця функція була визнана настільки важливою, оскільки з моменту впровадження властивостей, що реалізовувались автоматично в C # 3, змінні властивості (ті, що мають геттер та сеттер) стали швидше писати, ніж незмінні (ті, що мали лише геттер), тобто люди були спокуса використовувати змінні властивості, щоб уникнути необхідності вводити код для поля резервної копії, як правило, необхідного для властивостей лише для читання. Більше обговорень властивостей, що реалізуються автоматично, є у відповідному розділі Посібника з програмування Microsoft C # .
Цей допис у блозі "№1207 - 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; } }
Більш детально також можна ознайомитись у репозиторії мережі Roslyn на GitHub :
Авто-властивості тепер можна оголошувати без сеттера.
Поле резервної копії автовластивості, лише для отримання, неявно оголошується як лише для читання (хоча це має значення лише для цілей відображення). Його можна ініціалізувати за допомогою ініціалізатора властивості, як у прикладі вище. Крім того, властивість getter-only можна призначити в тілі конструктора типу оголошення, що призводить до присвоєння значення безпосередньо базовому полю:
Це стосується стислого вираження типів, але зауважте, що це також усуває важливу різницю в мові між змінними та незмінними типами: автоматичні властивості були скороченням, лише якщо ви бажаєте зробити свій клас змінним, і тому спокуса за замовчуванням щоб це було чудово. Тепер, завдяки автоматичним властивостям, які отримують лише геттер, ігрове поле вирівняно між змінним та незмінним.
і в проекті специфікації мови C # 6.0 (NB: Мовна специфікація остаточна щодо Microsoft, але вона ще не затверджена як стандарт EMCA / ISO , отже, "проект"):
Автоматично реалізовані властивості
Властивість, що автоматично реалізується (або коротше автовластивість), є не абстрактною властивістю, що не пов’язана із зовнішнім виглядом, з тілами доступу лише із крапкою з комою. Авто-властивості повинні мати доступ доступу, а за бажанням можуть мати встановлений доступ.
Коли властивість вказано як властивість, що автоматично реалізується, приховане поле резервної копії автоматично доступне для властивості, а засоби доступу реалізовані для читання та запису в це поле резервної копії. Якщо авто-властивість не має встановленого доступу, поле резервної копії вважається лише для читання (поля для читання). Подібно до поля лише для читання, автовластивість, яка має лише отримання, також може бути призначена в тілі конструктора класу, що включає. Таке присвоєння призначається безпосередньо до поля заповнення майна лише для читання.
Авто-властивість за бажанням може мати властивість_ініціалізатор, яка застосовується безпосередньо до поля резервної копії як змінний_ініціалізатор (ініціалізатори змінних).
CS0200 C# Property or indexer cannot be assigned to -- it is read onlyвикористання звичайного властивості. Чи вважаються "автоматичні властивості лише для отримання" лише для читання чи ні?
Це нова функція в C # 6 яка дозволяє створювати властивості лише для читання та ініціалізувати їх значення з конструктора (або вбудовано, коли ви їх оголошуєте).
Якщо ви спробуєте змінити значення цієї властивості поза конструктором, це дасть вам помилку компіляції.
Він доступний лише для читання в тому сенсі, що після ініціалізації його значення (вбудованого або всередині конструктора) ви не можете змінити його значення.
Якби неможливо було ініціалізувати властивість лише для читання з конструктора (або ініціалізатора автоматичних властивостей), то це було б марно, оскільки воно завжди повертало б значення за замовчуванням для свого типу (0 для чисел, нуль для посилальних типів ). Однакова семантика застосовувалася до полів лише для читання у всіх версіях C #.
Щоб визначити справжню властивість лише для отримання (яка не може бути ініціалізована з конструктора), потрібно вказати, що вона повертає як частину визначення:
public int Foo { get { return 5; } }
Або, коротше в C # 6:
public int Foo => 5;
“Лише для читання автоматично реалізовані властивості”
Перш за все хочу пояснити, що властивість подобається
public string FirstName { get; }
Відомий як "властивості, що реалізуються автоматично лише для читання"
Щоб перевірити це, ви можете запустити та перевірити наведений вище код за допомогою Visual Studio. Якщо ви зміните мовну версію з C # 6.0 на C # 5.0, то компілятор видасть наступний виняток Функція "лише для читання автоматично реалізовані властивості" недоступна в C # 5. Будь ласка, використовуйте мовну версію 6 або новішу.
щоб змінити версію мови C # відвідайте тут
Зараз я переходжу до Вашого другого питання
“Це лише геттер. Але коли я будую конструктор, я можу змінити значення "
Корпорація Майкрософт представляє "властивості, що реалізуються автоматично лише для читання", на логіці лише для читання. Як ми знаємо, що ключове слово "тільки для читання" доступне з C # 1.0. ми використовуємо ключове слово “readonly” як модифікатор поля, і це поле може бути призначене двома способами або під час оголошення, або в конструкторі того самого класу.
Таким же чином значення "властивостей лише для читання, що реалізуються автоматично" можна призначити двома способами
Шлях1 (на момент декларування):
public string FirstName { get; } = "Banketeshvar";
Way2 (у конструкторі того ж класу)
Person()
{
FirstName = "Banketeshvar";
}
Власність виключно для читання
Якщо ви шукаєте власність виключно для читання, тоді йдіть на це
public string FullName => "Manish Sharma";
тепер ви не можете призначити значення властивості “FullName” з конструктора. Якщо ви спробуєте це зробити, це призведе до наступних винятків
"Властивість або індексатор" Person.FullName "неможливо призначити - воно лише для читання"
Функція автоматичного властивості була додана до мови під час випуску 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" };
Заявлена змінна readonlyможе бути записана в конструкторі, але на мовах, які вшановують атрибут, не може бути змінена після повернення конструктора. Цей кваліфікатор був наданий як функція мови, оскільки він часто необхідний для полів, значення яких будуть змінюватися залежно від параметрів конструктора (тобто вони не можуть бути ініціалізовані до запуску конструктора), але їх не доведеться змінювати після повернення конструкторів, але це було придатний лише для змінних, виставлених як поля. Семантикаreadonly кваліфікованих полів у багатьох випадках була б ідеальною для публічних членів, за винятком того, що для класів часто краще виставляти членів - навіть незмінні - як властивості, а не як поля.
Подібно до того, як існують автоматичні властивості читання-запису, які дозволяють класам виставляти змінні властивості так само просто, як звичайні поля, існують автоматичні властивості лише для читання, які дозволяють класам виставляти незмінні властивості так само просто, як і readonly-кваліфіковані поля. Подібно до того, як readonly-кваліфіковані поля можна записати в конструктор, так і з властивостями get-only.