Предоставляет ли C# переменную, которая не может быть изменена? Это похоже на const
, но вместо того, чтобы присваивать ему значение в объявлении, переменная не имеет значения по умолчанию, но ей может быть присвоено значение только один раз во время выполнения (EDIT: и, возможно, не от конструктора). или это невозможно?переменная, которая не может быть изменена
ответ
Вы можете создать свой собственный универсальный класс, обеспечивающий эту функциональность, но это может быть излишним.
public class SetValueOnce<T>
{
public bool _set;
private T _value;
public SetValueOnce()
{
_value = default(T);
_set = false;
}
public SetValueOnce(T value)
{
_value = value;
_set = true;
}
public T Value
{
get
{
if(!_set)
throw new Exception("Value has not been set yet!");
return _value;
{
set
{
if(_set)
throw new Exception("Value already set!");
_value = value;
_set = true;
}
}
}
вы забыли некоторые кавычки –
@Louis, обновили, он должен быть синтаксически правильным, но я набирал непосредственно как блок кода как часть ответа - я бы не рекомендовал SO as редактор кода - Нет интеграции управления версиями для одной вещи :) –
Чтобы быть справедливым, я понимаю это, потому что это действительно с учетом требования в моем вопросе. Хотя на самом деле мне больше нравится ответ ck, и это на самом деле то, что мне нужно –
Вы можете объявить переменную readonly
, которая может быть установлена только в конструкторе или непосредственно через его объявление.
так должно быть от конструктора? –
Вы можете ограничить доступ и разрешить установку поля внутри своего класса, но 'readonly' и' const' - это единственные языковые конструкции, которые фактически позволяют устанавливать значение после построения или объявления. –
Да, либо его конструктор, либо встроенный внутри объявления (но точно так же, как и const). Также он должен быть внутри конструктора, а не только во время построения - это означает, что невозможно установить значение переменной readonly внутри функции, называемой конструктором. –
Несомненно. Вы можете использовать readonly
:
т.е .: public readonly int z;
Это может быть изменен только из конструктора.
От MSDN:
Вы можете присвоить значение только для чтения поле только в следующих контекстах:
Когда переменная инициализируется в объявлении, например:
public readonly int y = 5;
Для поля экземпляра в конструкторах экземпляра класса t hat содержит объявление поля или статическое поле в статическом конструкторе класса, который содержит объявление поля. Они также являются единственными контекстами, в которых можно передать поле readonly в качестве параметра
out
илиref
.
Если же Вы желаете сделать свойство, которое может быть изменено только в классе, который создал его, вы можете использовать следующее:
public string SetInClass
{
get;
private set;
}
Это позволяет вносить изменения в классе , но переменная не может быть изменена вне класса.
Вы можете определить переменную readonly, которая может иметь только значение, заданное в конструкторе объектов.
Читайте об этом здесь: http://msdn.microsoft.com/en-us/library/acdd6hb7%28v=VS.100%29.aspx
Можно отметить поле readonly
что потребует установить это значение либо в точке декларации или в конструкторе, а затем предотвратит его от переназначены после строительства.
Однако, пока ссылка будет доступна только для чтения, объект не обязательно будет слишком. Чтобы предотвратить изменение самого объекта, вам придется сделать тип неизменным или предоставить класс-оболочку, который предоставляет только неразрушающие методы и свойства базового типа.
Вы можете свернуть свой собственный, используя пользовательский сеттер (но не используйте Object
, если Вы не должны выбрать правильный класс):
private Object myObj = null;
private Boolean myObjSet = false;
public Object MyObj
{
get { return this.myObj; }
set
{
if (this.myObjSet) throw new InvalidOperationException("This value is read only");
this.myObj = value;
this.myObjSet = true;
}
}
EDIT:
Это Безразлично» t прекратить закрытие частного поля внутренними классами.
@Kyle, Почему? если вы посмотрите на вышеизложенное, это говорит о том, что он не может быть установлен из конструктора, который исключает только чтение! выглядит как действительная реализация для меня, учитывая требования OP! – OneSHOT
wow отличная идея! –
@ Louis, так как Kyle и OneSHOT говорят, что нет ничего, что помешало бы классу изменять значение столько раз, сколько оно было бы, поскольку оно может напрямую обращаться к частной переменной. –
Если вы хотите назначить переменную во время выполнения после того, как объект, содержащий ее, вы можете использовать настраиваемое свойство с методом setter, который может быть изменен только один раз. то есть.
private myVariable = null;
public object MyVariable
{
get { return myVariable; }
set { if(myVariable == null) myVariable = value;
}
Да, в C# есть несколько способов сделать это.
Прежде всего, что такое «переменная»? Переменная - это место хранения. Локальные переменные, формальные параметры методов (и индексаторы, конструкторы и т. Д.), Статические поля и экземпляры, элементы массива и разметки указателя - все переменные.
Некоторые переменные могут быть объявлены как «только для чтения». Переменная «readonly» может быть изменена только один раз, либо инициализатором в объявлении, либо в конструкторе. Только декларации полей могут быть прочитаны только; C# не поддерживает объявленные пользователем локали только для чтения.
Существуют определенные ограничения на переменные readonly, которые гарантируют, что нормальная работа C# не вносит мутации. Это может привести к неожиданным результатам! См
http://ericlippert.com/2008/05/14/mutating-readonly-structs/
для деталей.
Некоторые местные жители также эффективно читают. Например, когда вы говорите using(Stream s = whatever)
, то внутри встроенного оператора using
вы не можете изменить значение s. Причиной этого ограничения является предотвращение ошибки, при которой вы создаете ресурс, который должен быть удален, и затем утилизировать другой ресурс, когда содержимое переменной s расположено. Лучше быть тем же.
(К сожалению, в C# есть ошибки, связанные с ситуацией, когда выделенный ресурс является типом структуры, структура имеет метод, который мутирует структуру, а локальная переменная является или не является закрытой локалью анонимной функции . или итератор блок, так как сценарии неясны и исправление будет потенциально ломать мы не сделали ничего об этом еще в ожидании дальнейшего анализа)
локальная переменная, объявленная в foreach
заявлении также эффективно readonly
- что переменные изменяют значение каждый раз через цикл, но вам не разрешено изменять его значение.
Невозможно сделать формальный параметр readonly, элемент массива или разыменование указателя.
Существуют различные способы «разбить» ограничение на чтение и записать в переменную, которая должна быть только для чтения.Вы можете использовать Reflection или небезопасный код, чтобы существенно сократить любое ограничение безопасности CLR, если у вас есть достаточные привилегии для этого. Если это причиняет боль, когда вы это делаете, не делайте этого; с этими полномочиями лежит ответственность за то, что вы делаете, и делайте все правильно.
+1 для объяснения немного больше о внутренних C# .. Очень образовательны! – Arcturus
«Только декларации полей могут быть только для чтения, а C# не поддерживает объявленные пользователем локальные пользователи.» Хотя примитивные, строковые, enum и valueType производные локали могут быть объявлены * const *, что фактически одно и то же для этих типов (хотя, возможно, оно ближе к литеральному псевдониму, чем локальная переменная, доступная только для чтения). –
@Paul: Но, конечно, это не * переменные *. Константы не являются переменными, потому что * constant * и * variable * являются * противоположностями *. (И вы ошибаетесь, чтобы сказать, что локали, основанные на ValueType, могут быть константами. Уверяю вас, они не могут. Я подозреваю, что вы думаете о каком-то другом языке, возможно, C++.) –
Поскольку similar question был недавно спросил @Ivan, позвольте мне предложить еще один способ создать экземпляр свойства в любом месте в коде, конечно, более точно, при поддержке универсального конструктора.
public class Immutable<T> {
public T Val { get; private set; }
public Immutable(T t) {
Val = t;
}
}
Usage будет
var immutableInt1 = new Immutable<int>(3); // you can set only once
immutableInt1.Val = 5; // compile error here: set inaccessible
Console.WriteLine("value: " + immutableInt1.Val);
Дело в том, что теперь вы получаете компилировать ошибку, если вы пытаетесь установить новое значение.
Помимо этого, я считаю, что вам лучше использовать функциональный язык, например, F # вместо C#, если вы хотите следовать этой парадигме.
- 1. переменная не может быть изменена
- 2. C# Переменная, которая не может быть изменена вне функции
- 3. Переменная C++, которая может быть изменена только одним способом, возможно?
- 4. Переменная сессии может быть изменена хакером?
- 5. C# переменная, которая не может быть изменена, но должны быть парафированы в конструкторе
- 6. SSIS Переменная, которая прагматически изменена
- 7. переменная в обратном вызове не может быть изменена
- 8. Почему переменная-член структуры не может быть изменена в функции?
- 9. Почему моя переменная не может быть изменена для анимации киви?
- 10. Почему локальная переменная не может быть изменена во внутреннем классе?
- 11. переменная не может быть изменена в другом классе
- 12. Есть ли часть файла Windows, которая не может быть изменена?
- 13. Как установить таблицу модели Django, которая не может быть изменена?
- 14. Сохраненная ранее запись не может быть изменена
- 15. Заключительный объект может быть изменен, но ссылочная переменная не может быть изменена
- 16. Объектная переменная не изменена
- 17. проверить, не изменена ли переменная
- 18. Странное поведение в постоянном методе, где переменная может быть изменена
- 19. Ручка базы данных, которая может быть изменена в приложении Android?
- 20. Как для будущего ссылки на страницу, которая может быть изменена
- 21. как создать постоянную переменную, которая может быть изменена постоянно
- 22. Графика Java не может быть изменена Шрифт
- 23. Angular2/TypeScript - переменная не изменена
- 24. Переменная не может быть установлена
- 25. как сделать как ярлык из части моей формы, которая может быть изменена и изменена
- 26. Почему переменная таблицы Matlab может быть изменена с использованием старого значения, но строка ячейки не может?
- 27. Переменная не может быть парафировано
- 28. «Переменная не может быть инициализирован»
- 29. Переменная не может быть инициализирована
- 30. Переменная не может быть разрешена
Лингвистический nitpick: «переменная, которая не может быть изменена» является оксюмороном. – LukeH