Я ищу эквивалент C# Java final
. Это существует?
Делает C#, имеют что-либо как следующее:
public Foo(final int bar);
В вышеупомянутом примере, bar
переменная только для чтения и не может быть изменена Foo()
. Там какой-либо путь состоит в том, чтобы сделать это в C#?
Например, возможно, у меня есть длинный метод, который будет работать с x
, y
, и z
координаты некоторого объекта (ints). Я хочу быть абсолютно уверенным, что функция не изменяет эти значения всегда, таким образом, повреждая данные. Таким образом я хотел бы объявить их только для чтения.
public Foo(int x, int y, int z) {
// do stuff
x++; // oops. This corrupts the data. Can this be caught at compile time?
// do more stuff, assuming x is still the original value.
}
К сожалению, на C # это невозможно.
Ключевое слово const
может использоваться только для локальных переменных и полей.
Ключевое слово readonly
может использоваться только для полей.
ПРИМЕЧАНИЕ. Язык Java также поддерживает окончательные параметры метода. Эта функция отсутствует в C #.
из http://www.25hoursaday.com/CsharpVsJava.html
РЕДАКТИРОВАТЬ (2019/08/13):
Я добавляю это для наглядности, поскольку это принято и самый высокий в списке. Теперь это возможно с в параметрах
. Подробнее см. ответ под этим.
Я начну с части int
. int
- это тип значения, а в .Net это означает, что вы действительно имеете дело с копией. Это действительно странное конструктивное ограничение - сказать методу: «У вас может быть копия этого значения. Это ваша копия, а не моя; я никогда ее больше не увижу. Но вы не можете изменить копию». В вызове метода неявно подразумевается, что копирование этого значения допустимо, иначе мы не могли бы безопасно вызвать метод. Если для метода требуется оригинал, оставьте разработчику сделать копию для сохранения. Либо присвойте методу значение, либо не присвойте значение методу. Не делайте перерывов между делом.
Перейдем к ссылочным типам. Теперь это немного сбивает с толку. Вы имеете в виду постоянную ссылку, где сама ссылка не может быть изменена, или полностью заблокированный неизменяемый объект? В первом случае ссылки в .Net по умолчанию передаются по значению. То есть вы получаете копию справки. Таким образом, мы имеем практически такую же ситуацию, что и для типов значений. Если разработчику потребуется исходная ссылка, он может оставить ее себе.
Остается только постоянный (заблокированный / неизменяемый) объект. Это может показаться нормальным с точки зрения времени выполнения, но как компилятор может обеспечить это? Поскольку свойства и методы могут иметь побочные эффекты, вы, по сути, будете ограничены доступом к полю только для чтения. Такой объект вряд ли будет очень интересным.
Вот короткое и приятное ответ, который, вероятно, получит много голосов против. Я не прочитал все сообщения и комментарии, поэтому, пожалуйста, простите меня, если это было предложено ранее.
Почему бы не взять ваши параметры и не передать их объекту, который выставляет их как неизменяемые, а затем использовать этот объект в своем методе?
Я понимаю, что это, вероятно, очень очевидный обходной путь, который уже рассматривался, и OP является пытаясь избежать этого, задав этот вопрос, но я чувствовал, что он, тем не менее, должен быть здесь ...
Удачи: -)
Если вы часто сталкиваетесь с подобными проблемами, то вам стоит подумать о "венгерских приложениях". Хороший вид, в отличие от плохого вида. Хотя это обычно не пытается выразить постоянство параметра метода (это просто слишком необычно), ничто не мешает вам добавить дополнительную букву "c" перед именем идентификатора.
Для всех тех, кто хочет нажать кнопку downvote, пожалуйста, прочитайте мнения этих светил по данной теме:
Если struct передается в метод, если только он не передается по ссылке, он не будет изменен методом, в который передается. Так что в этом смысле - да.
Можете ли вы создать параметр, значение которого не может быть присвоено в методе или свойства которого не могут быть установлены в методе? Нет. Вы не можете предотвратить присвоение значения в методе, но вы можете предотвратить установку его свойств, создав неизменяемый тип.
Вопрос не в том, можно ли присвоить параметр или его свойства внутри метода. Вопрос в том, чем он станет после выхода из метода.
Единственный случай, когда внешние данные будут изменены, это если вы передадите класс и измените одно из его свойств, или если вы передадите значение, используя ключевое слово ref. В описанной вами ситуации нет ни того, ни другого.