В C++ для определения локальной константы времени выполнения можно написать так: const auto c = f() Далее, все попытки изменить c будут приводить к ошибке компиляции. В C# такой возможности нет. Можно использовать readonly член подобным образом, но не локальную константу. Почему существует такое ограничение (в чём причина отсутствия локальных констант а-ля C++) и какое каноническое решение имеется для обеспечения локальной константности времени выполнения на C#? Неужели для этого надо создавать отдельный read-only интерфейс?
Ответ Ответы: JaredPar, и Jon Skeet Одна из причин - отсутствие поддержки CLR для локальных переменных только для чтения. Readonly переводится в CLR/CLI initonly опкод. Этот флаг может быть применен только к полям и не имеет смысла для локальных переменных. Фактически, применение этого кода к локальным переменным скорее всего сделает код непроверяемым. Это не значит, что C# не может реализовать это. Но это добавляет два смысла для одной и той же языковой конструкции. Версия для локальных переменных не будет иметь в CLR эквивалентного отображения.
Обращаясь к ответу Jared'а, это возможно может быть compile-time фичей - компилятор будет запрещать тебе писать в переменную после первоначального объявления (которое должно включать присвоение). Есть ли в этом польза? Потенциальная - но не большая, если быть честным. Если ты не можешь сказать будет или нет присваивание еще где-то в методе, то твой метод слишком большой. Как бы то ни было, в Java есть эта особенность (при использовании модификатора final) и я очень редко видел его использование в случаях отличных от разрешения использования переменной в внутреннем анонимном классе - и где это было использовано это давало скорее впечатление беспорядка, чем полезной информации.
в качестве обходного пути, если очень хочется, только на свой страх и риск есть такой: Настолько отличный, насколько ужасный пример В качестве run-time константы можно использовать переменную в блоке итератора: public void f() { foreach (int n in new int[] { getNum() }) // n declared constant { n = 3 // won't compile: "error CS1656: Cannot assign to 'n' because it is a 'foreach iteration variable'" } }