Поговорите об этом с коллегой по работе. У нас есть некоторые мысли по этому поводу, но нам интересно, что думает по этому поводу SO толпа?
c#
immutability
language-design
readonly
Брайан Генизио
источник
источник
Ответы:
Одна из причин - отсутствие поддержки CLR для локального файла только для чтения. Только чтение транслируется в код операции CLR / CLI только для инициализации. Этот флаг может применяться только к полям и не имеет значения для локального. Фактически, применение его к локальному, скорее всего, приведет к созданию непроверяемого кода.
Это не значит, что C # не может этого сделать. Но это даст два разных значения одной и той же языковой конструкции. Версия для местных жителей не будет иметь сопоставления, эквивалентного CLR.
источник
readonly
Ключевое слово для полей должно поддерживаться CLI , поскольку его эффект является видимым для других узлов. Все это будет означать, что переменная имеет только одно назначение в методе во время компиляции.const
(который в C ++ больше похож на C #,readonly
чем на C #const
, хотя он может играть обе роли). Тем не менее, C ++ поддерживаетconst
локальные автоматические переменные. Следовательно, отсутствие поддержки CLR для C #readonly
для локальной переменной не имеет значения.using
иout
делают именно это, и мир не рухнул.Я думаю, что это плохое суждение со стороны архитекторов C #. Модификатор readonly для локальных переменных помогает поддерживать корректность программы (как и утверждения) и потенциально может помочь компилятору оптимизировать код (по крайней мере, в случае других языков). Тот факт, что он сейчас запрещен в C #, является еще одним аргументом в пользу того, что некоторые из «функций» C # являются просто применением личного стиля кодирования его создателей.
источник
Обращаясь к ответу Джареда, это, вероятно, должно быть просто функцией времени компиляции - компилятор запретит вам писать в переменную после первоначального объявления (которое должно включать присваивание).
Могу ли я увидеть в этом ценность? Потенциально - но, если честно, не очень. Если вы не можете легко определить, будет ли переменная назначена где-либо еще в методе, значит, ваш метод слишком длинный.
Для чего это стоит, Java имеет эту функцию (используя
final
модификатор) , и я очень редко видел его использовали другие , чем в тех случаях , когда оно имеет быть использовано , чтобы позволить переменной быть захваченными анонимного внутреннего класса - и где он находится при использовании он создает впечатление беспорядка, а не полезной информации.источник
readonly
/final
значение из переменных с егоval
иvar
ключевыми словами. В коде Scala локальныеval
s используются очень часто (и фактически предпочтительнее локальныхvar
). Я подозреваю, что основными причинами того, чтоfinal
модификатор не используется более часто в Java, являются а) беспорядок и б) лень.readonly
это не будет слишком важно. С другой стороны, для локальных переменных, которые используются в замыканиях,readonly
во многих случаях компилятор может генерировать более эффективный код. В настоящее время, когда выполнение входит в блок, содержащий замыкание, компилятор должен создать новый объект кучи для закрытых переменных, даже если код, который использовал бы замыкание, никогда не выполняется . Если бы переменная была доступна только для чтения, код вне замыкания мог бы использовать обычную переменную; только когда создается делегат для закрытия ...Команда разработчиков C # 7 вкратце обсудила предложение только для чтения locals и параметров для. Из заметок о совещании разработчиков C # от 21 января 2015 г . :
Обсуждение продолжается в репозитории C # Language Design. Проголосуйте, чтобы показать свою поддержку. https://github.com/dotnet/csharplang/issues/188
источник
Это недосмотр разработчика языка C #. В F # есть ключевое слово val, и он основан на CLR. Нет причин, по которым C # не может иметь ту же языковую функцию.
источник
Я был тем коллегой, и это было неприятно! (просто шучу)
Я бы не стал исключать эту возможность, потому что лучше писать короткие методы. Это немного похоже на то, что вы не должны использовать потоки, потому что они сложны. Дайте мне нож и позвольте мне не порезаться.
Лично мне нужно другое ключевое слово типа «var», например «inv» (invarient) или «rvar», чтобы избежать беспорядка. В последнее время я изучаю F # и нахожу неизменное привлекательным.
Никогда не знал, что у Java есть это.
источник
Мне нужны локальные переменные только для чтения так же, как мне нравятся локальные константные переменные. Но он менее приоритетен, чем другие темы.
Возможно, его приоритет является той же причиной, по которой дизайнеры C # (пока!) Не реализовали эту функцию. Но в будущих версиях должно быть легко (и иметь обратную совместимость) поддержка локальных переменных только для чтения.
источник
Только чтение означает, что единственное место, где может быть установлена переменная экземпляра, - это конструктор. При локальном объявлении переменной у нее нет экземпляра (он находится только в области видимости), и конструктор не может его коснуться.
источник
Я знаю, это не ответ на ваш вопрос. В любом случае, читатели этого вопроса, тем не менее, могут оценить приведенный ниже код.
Если вы действительно заинтересованы в том, чтобы выстрелить себе в ногу при переопределении локальной переменной, которая должна быть установлена только один раз, и вы не хотите делать ее более доступной глобально, вы можете сделать что-то вроде этого.
Пример использования:
Может быть, не меньше кода,
rvar rInt = 5
но он работает.источник
Вы можете объявить локальные переменные только для чтения в C #, если вы используете интерактивный компилятор C #
csi
:Вы также можете объявить локальные переменные только для чтения в
.csx
формате скрипта.источник
message
это не переменная, она скомпилирована в поле. Это не придирки, потому что различие явно существует и в интерактивном C #:int x; Console.WriteLine(x)
разрешен интерактивный C # (потому чтоx
это поле и неявно инициализировано), ноvoid foo() { int x; Console.WriteLine(x); }
нет (потому чтоx
это переменная и используется до ее назначения). Кроме того,Expression<Func<int>> y = x; ((MemberExpression) y.Body).Member.MemberType
будет показано, чтоx
это действительно поле, а не локальная переменная.С # уже имеет переменную только для чтения, хотя и с несколько другим синтаксисом:
Рассмотрим следующие строки:
Сравнить с:
По общему признанию, первым решением могло бы быть меньше кода для написания. Но второй фрагмент делает явным только чтение при ссылке на переменную.
источник
readonly var im = new List<string>(); im.Add("read-only variable, mutable object!");
.используйте
const
ключевое слово, чтобы сделать переменную только для чтения.ссылка: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const
источник
const
котором переменная может быть назначена только во время ее инициализации, а не стиль csharp, вconst
котором могут использоваться только выражения времени компиляции. Например, вы не можете этого сделать,const object c = new object();
ноreadonly
местный житель позволит вам это сделать.Я думаю, это потому, что функция, имеющая переменную только для чтения, может никогда не быть вызвана, и, вероятно, что-то в ней выходит за рамки, и когда вам это нужно?
источник