To create a readonly auto-implemented property, give it a private set accessor.
Слово 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.
В объединенной спецификации C# 3.0 сказано следующее:
It is however possible to set the access level of each accessor differently. Thus, the effect of a read-only property with a private backing field can be mimicked like this:
public class ReadOnlyPoint {
public int X { get; private set; }
public int Y { get; private set; }
public ReadOnlyPoint(int x, int y) { X = x; Y = y; }
}
Что же получается на самом деле?
public int X { get; private set; }
просто генерирует свойство с private set аксессором, которое не запрещено модифицировать в любом месте класса, что не соответствует поведению поля с readonly модификатором.
Таким образом, при необходимости достижения поведения как у readonly поля, пользоваться auto-implemented properties нельзя.
Собственно что тут обсуждать — не знаю. Есть такие, что расстроены этим фактом как я?
Здравствуйте, SiAVoL, Вы писали:
SAV>Здравствуйте, BOleg, Вы писали:
BO>>Хм. А как Вы себе представляете синтаксис инициализации readonly свойства? Не поля, а свойства. SAV>
Здравствуйте, _FRED_, Вы писали:
BO>>Хм. А как Вы себе представляете синтаксис инициализации readonly свойства? Не поля, а свойства.
_FR>Да, в данный момент этого нет, но в блогах встречаются предложения относительно того, как бы это могло выглядеть в одной их следующих версий.
Добавлю, что я лично представляю себе это так:
public int Property { get; readonlyset; }
где "readonly" перед set означает, что акессор закрытый (private) и может быть вызван только из конструктора класса, в котором объявлено свойство.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, _FRED_, Вы писали:
BO>>>Хм. А как Вы себе представляете синтаксис инициализации readonly свойства? Не поля, а свойства.
_FR>>Да, в данный момент этого нет, но в блогах встречаются предложения относительно того, как бы это могло выглядеть в одной их следующих версий.
_FR>Добавлю, что я лично представляю себе это так: _FR>
_FR>public int Property { get; readonlyset; }
_FR>
_FR>где "readonly" перед set означает, что акессор закрытый (private) и может быть вызван только из конструктора класса, в котором объявлено свойство.
Вариант! Только не очень вяжется — вроде readonly, но set
Учитывая, что в чисто-set авто-свойствах смысла нет, можно было бы вообще обходиться чем-то вроде:
Здравствуйте, BOleg, Вы писали:
BO>Здравствуйте, samius:
BO>Хм. А как Вы себе представляете синтаксис инициализации readonly свойства? Не поля, а свойства.
например, как предложил _FRED_ — readonly set. Для этого было бы достаточно лишь изменений на уровне компилятора — объявление readonly поля и обращение к нему в конструкторе либо при инициализации.
Но дело не только в этом. Дело в том, что прочитав документацию и не заглянув при этом в Reflector, я ошибочно ожидал другого поведения AI свойств. К чему была ссылка на readonly поля? Думаю, что это ввело в заблуждение не только меня.
С того момента как я начал использовать AI свойства, подразумевая их поведение схожим с readonly полями было написано довольно много кода, который теперь желательно исправить.
Вобщем, как-то не очень хочется проводить много времени проверяя реализацию на расхождение с документацией перед тем как использовать какую-то фичу языка и не только.
Здравствуйте, _FRED_, Вы писали: _FR>где "readonly" перед set означает, что акессор закрытый (private) и может быть вызван только из конструктора класса, в котором объявлено свойство.
А может он быть вызван из приватного метода, который я вызываю только из конструктора?
На мой взгляд, private set — это самое то что нужно в данном случае. По крайней мере, выглядит на порядок лучше, чем те же автоевенты, с двусмысленностью поведения в зависимости от места расположения обращающегося кода.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
_FR>>где "readonly" перед set означает, что акессор закрытый (private) и может быть вызван только из конструктора класса, в котором объявлено свойство. S>А может он быть вызван из приватного метода, который я вызываю только из конструктора? S>На мой взгляд, private set — это самое то что нужно в данном случае.
Мне бы хотелось иметь гарантию того, что значение свойства не изменит никто (ни один метод), кроме кода конструктор[а|ов], , что бы это (readonly для свойств) работало точно так же как и readonly-поля.
Гораздо боолее (сейчас только вспомнил) интересным кажется предложение от кого-то в одном из недавних обсуждений на этом вот форуме: что бы имя свойства внутри класса, его объявившего, интерпретировалось бы как имя поля (тогда можно было бы передавать такие свойства как ref-параметры, например), а снаружи — уже как обычное свойство. Было бы по аналогии с событиями.
S>По крайней мере, выглядит на порядок лучше, чем те же автоевенты, с двусмысленностью поведения в зависимости от места расположения обращающегося кода.
Проблема там не столько с "местом расположения обращающегося кода", как с захардкоженной синхронизацией. К счастью, теперь уже у комрадов хватило ума не добавлять MethodImpl(MethodImplOptions.NoInlining) к свойствам.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, _FRED_, Вы писали: _FR>>где "readonly" перед set означает, что акессор закрытый (private) и может быть вызван только из конструктора класса, в котором объявлено свойство. S>А может он быть вызван из приватного метода, который я вызываю только из конструктора?
В документации указана аналогия с readonly свойствами, а к ним обращение из private методов не позволяется, даже если private метод вызывается только из конструктора. И это верно, потому как private метод может быть вызван с помощью Reflection-а, и никаких гарантий что он будет вызван из конструктора нет.
S>На мой взгляд, private set — это самое то что нужно в данном случае. По крайней мере, выглядит на порядок лучше, чем те же автоевенты, с двусмысленностью поведения в зависимости от места расположения обращающегося кода.
private set — вещь нужная. Было бы не совсем корректно, если бы она себя действительно вела так, как написано в документации. Нехватает именно поведения аналогичного readonly полям, но с другим синтаксисом. А так же адекватной документации.
Здравствуйте, _FRED_, Вы писали:
_FR>Здравствуйте, MxKazan, Вы писали:
MK>>Учитывая, что в чисто-set авто-свойствах смысла нет, можно было бы вообще обходиться чем-то вроде: _FR>
MK>>public int Property { readonly; }
_FR>
_FR>В таком варианте смущает то, что это ни на что не похоже. Самый, наименее меняющий существующий синтаксис, всё-таки был предложен в самом начале
. Разве что возможность объявлять set-тер кажется абсолютно избыточной (ничего кроме "private set;" там быть не может) и потому лишней.
Как раз не соглашусь с этим. В варианте, когда readonly впереди, мы делаем двойную работу. Понятно, что такой идентификатор неприменим к обычным свойствам. Значит оно auto-implemented. Но, пардон, зачем тогда дальше описывать, что оно get? В случае когда readonly пишется внутри, мы имеем однотипные конструкции для объявления всех видов свойств, уточняя варианты доступа на уровне аксессоров (имеется ввиду, что readonly пишется в блоке описания аксессоров).
Здравствуйте, samius, Вы писали:
S>Здравствуйте, MxKazan, Вы писали:
MK>>Здравствуйте, _FRED_, Вы писали:
_FR>>>Здравствуйте, MxKazan, Вы писали: S>[skipped]
S>раз уж решили пофантазировать на эту тему, то хочется в синтаксисе учесть возможность инициализации при объявлении, а не только в конструкторе.
S>ИМХО, для readonly свойств можно делать объявление таким: S>
public int MyIntProperty { get; }
S>И это бы вполне соответствовало идее readonly и не изменяло бы синтаксис. S>Но куда присовокупить инициализацию?
We are already investigating readonly autoproperties, although it is too early to say if they'll make it into the next release. With the many declarative constructs introduced in C# 3.0 we are keen for people to adopt a programming style that depends less on mutation. It is therefore a little ironic that autoprops currently only exist in a mutable form.
Thanks again for your suggestion. After having done feature planning for the next release of C# I regret to say that this feature is not being added. We have to do some harsh prioritization, both because of our implementation and testing resources, but also because we need to keep the number of new langauge features at a manageable level — depending on how you count, we are adding only four language features to C# this time around. Unfortunately many great suggestions just can't make it in because of that.
I apologize that this is a "canned" follow-up answer, sent out as a result of our feature planning for the next release. In most cases I or someone else already replied individually to your suggestion — please let us know if you feel it hasn't been adequately addressed.
Thanks again for taking the time to share your ideas with us. Please keep them coming!
Mads Torgersen, C# Language PM.
По поводу инициализации автосвойств:
We decided to keep auto-props really simple. You can easily initialize them by calling the setter from the constructor.
Thanks,
Mads Torgersen, C# Language PM
... << RSDN@Home 1.2.0 alpha 4 rev. 1111 on Windows Vista 6.0.6001.65536>>
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, samius, Вы писали:
AVK>По поводу readonly автосвойств: AVK>
We are already investigating readonly autoproperties, although it is too early to say if they'll make it into the next release. With the many declarative constructs introduced in C# 3.0 we are keen for people to adopt a programming style that depends less on mutation. It is therefore a little ironic that autoprops currently only exist in a mutable form.
AVK>Thanks again,
AVK>Mads Torgersen, C# Language PM
Да, занятно, что они тоже так считают )))
Но, ничего смертельного нет в том, чтобы продолжать писать свойства руками, сниппетами или пр.
Здравствуйте, AndrewVK, Вы писали:
AVK>По поводу readonly автосвойств: AVK>
We are already investigating readonly autoproperties, although it is too early to say if they'll make it into the next release. With the many declarative constructs introduced in C# 3.0 we are keen for people to adopt a programming style that depends less on mutation. It is therefore a little ironic that autoprops currently only exist in a mutable form.
Это с коннекта? Можно ссылку?
Кстати, ты как-то говорил, что как раз в одной из блмжайших версий CLR собираются добавить оптимизаций. Не ожидается ли оптимизаций, свзязанных с readonly-полями?
AVK>По поводу инициализации автосвойств: AVK>
We decided to keep auto-props really simple. You can easily initialize them by calling the setter from the constructor.
ИМХО, более чем оправдано.
Help will always be given at Hogwarts to those who ask for it.