To create a readonly auto-implemented property, give it a private set accessor.считал, что auto-implemented readonly свойства имеют отношение к ключевому слову readonly. Вот цитата из описания этого ключевого слова:
The readonly keyword is a modifier that you can use on fields. When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.Именно на эту статью в документации ведет гиперссылка из статьи про auto-implemented свойства. Воображение рисовало такую реализацию этого нововведения компилятором, где бы код
class Foo { public int MyProperty { get; private set; } public Foo(int p) { MyProperty = p; } }соответствовал бы следующей реализации:
class Foo { private readonly int _autoGeneratedReadonlyField; public Foo(int p) { autoGeneratedReadonlyField = p; } public int MyProperty { get { return _autoGeneratedReadonlyField; } } }Таким образом, такая реализация auto-implemented свойства с private set аксессором, максимально соответствовала бы документации. Так получилось, что довольно долго я считал, что readonly auto-implemented свойства нельзя модифицировать нигде, кроме конструктора класса (либо статического конструктора, если свойство статическое). Оказалось, что private set не генерит ничего кроме private аксессора к свойству, обращение к которому разрешено из кода любого метода или свойства класса, либо вложенных классов.
Итого, использование readonly auto-implemented свойств не имеет никакого отношения к readonly полям класса. Зачем же тогда в документации стоит эта ссылка на описание ключевого слова readonly? Думаю, что кроме меня есть еще жертвы дезинформации.
Вообще говоря, поведение private set модификатора auto-implemented свойства выбрано правильно. И такое поведение нужно, но кроме этого нужна адекватная документация. Все же, эмуляция readonly полей нужна. И на форуме в RSDN было предложено несколько вариантов синтаксиса, которые могли бы быть реализованы. Например,
public readonly string MyString { get; } public int Property { get; readonly set; } public int Property { readonly; }Удобен был бы способ инициализации таких свойств при объявлении (по аналогии с полями).
Реализую свойства вручную, не использую автосвойста, только для того чтобы везде вписать readonly. И мне себя не жалко, семантика дороже :-)
ОтветитьУдалитьВ продакшн коде тоже делаю именно так. А в прототипе могу и полениться.
ОтветитьУдалить