Параметры могут быть постоянными?

Я ищу эквивалент 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.
}
79
задан John Saunders 16 October 2014 в 16:52
поделиться

5 ответов

К сожалению, на C # это невозможно.

Ключевое слово const может использоваться только для локальных переменных и полей.

Ключевое слово readonly может использоваться только для полей.

ПРИМЕЧАНИЕ. Язык Java также поддерживает окончательные параметры метода. Эта функция отсутствует в C #.

из http://www.25hoursaday.com/CsharpVsJava.html

РЕДАКТИРОВАТЬ (2019/08/13): Я добавляю это для наглядности, поскольку это принято и самый высокий в списке. Теперь это возможно с в параметрах . Подробнее см. ответ под этим.

59
ответ дан 24 November 2019 в 10:17
поделиться

Я начну с части int . int - это тип значения, а в .Net это означает, что вы действительно имеете дело с копией. Это действительно странное конструктивное ограничение - сказать методу: «У вас может быть копия этого значения. Это ваша копия, а не моя; я никогда ее больше не увижу. Но вы не можете изменить копию». В вызове метода неявно подразумевается, что копирование этого значения допустимо, иначе мы не могли бы безопасно вызвать метод. Если для метода требуется оригинал, оставьте разработчику сделать копию для сохранения. Либо присвойте методу значение, либо не присвойте значение методу. Не делайте перерывов между делом.

Перейдем к ссылочным типам. Теперь это немного сбивает с толку. Вы имеете в виду постоянную ссылку, где сама ссылка не может быть изменена, или полностью заблокированный неизменяемый объект? В первом случае ссылки в .Net по умолчанию передаются по значению. То есть вы получаете копию справки. Таким образом, мы имеем практически такую ​​же ситуацию, что и для типов значений. Если разработчику потребуется исходная ссылка, он может оставить ее себе.

Остается только постоянный (заблокированный / неизменяемый) объект. Это может показаться нормальным с точки зрения времени выполнения, но как компилятор может обеспечить это? Поскольку свойства и методы могут иметь побочные эффекты, вы, по сути, будете ограничены доступом к полю только для чтения. Такой объект вряд ли будет очень интересным.

8
ответ дан 24 November 2019 в 10:17
поделиться

Вот короткое и приятное ответ, который, вероятно, получит много голосов против. Я не прочитал все сообщения и комментарии, поэтому, пожалуйста, простите меня, если это было предложено ранее.

Почему бы не взять ваши параметры и не передать их объекту, который выставляет их как неизменяемые, а затем использовать этот объект в своем методе?

Я понимаю, что это, вероятно, очень очевидный обходной путь, который уже рассматривался, и OP является пытаясь избежать этого, задав этот вопрос, но я чувствовал, что он, тем не менее, должен быть здесь ...

Удачи: -)

7
ответ дан 24 November 2019 в 10:17
поделиться

Если вы часто сталкиваетесь с подобными проблемами, то вам стоит подумать о "венгерских приложениях". Хороший вид, в отличие от плохого вида. Хотя это обычно не пытается выразить постоянство параметра метода (это просто слишком необычно), ничто не мешает вам добавить дополнительную букву "c" перед именем идентификатора.

Для всех тех, кто хочет нажать кнопку downvote, пожалуйста, прочитайте мнения этих светил по данной теме:

3
ответ дан 24 November 2019 в 10:17
поделиться

Если struct передается в метод, если только он не передается по ссылке, он не будет изменен методом, в который передается. Так что в этом смысле - да.

Можете ли вы создать параметр, значение которого не может быть присвоено в методе или свойства которого не могут быть установлены в методе? Нет. Вы не можете предотвратить присвоение значения в методе, но вы можете предотвратить установку его свойств, создав неизменяемый тип.

Вопрос не в том, можно ли присвоить параметр или его свойства внутри метода. Вопрос в том, чем он станет после выхода из метода.

Единственный случай, когда внешние данные будут изменены, это если вы передадите класс и измените одно из его свойств, или если вы передадите значение, используя ключевое слово ref. В описанной вами ситуации нет ни того, ни другого.

0
ответ дан 24 November 2019 в 10:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: