Я прочитал о const
и static readonly
полей. У нас есть несколько классов, которые содержат только постоянные значения. Используется для различных вещей в нашей системе. Так что мне интересно, если мои наблюдения верны:
Должны ли такого рода постоянные значения всегда быть static readonly
для всего, что является публичным? И использовать только const
для внутренних / защищенных / частных ценностей?
Что вы порекомендуете? Должен ли я даже не использовать static readonly
поля, а использовать свойства, может быть?
static readonly
: попробуйте использовать const внутри,IEnumerator
который вызовет необратимое,yield
и вы получите страшную «Внутреннюю ошибку компилятора» . Я не тестировал код вне Unity3D, но я уверен, что это ошибка в моно или .NET . Это C # вопрос , тем не менее.static readonly
не может использоваться вswitch-case
выражении какcase
переменная,const
для этого требуется.static readonly
также нельзя использовать в качестве параметра атрибутаОтветы:
public static readonly
поля немного необычны;public static
свойства (только с aget
) будут более распространенными (возможно, подкрепленнымиprivate static readonly
полем).const
значения записываются непосредственно в колл-сайт; это обоюдоострый:Если значение никогда не изменится, тогда const в порядке - и
Zero
т. Д. Делают разумные const; p Кроме того,static
свойства более распространены.источник
readonly
поля не могут использоваться в выражениях switch / case, вместо этого вам нужно, чтобы они былиconst
.Я бы использовал,
static readonly
если Потребитель находится в другой сборке. Наличиеconst
и Потребителя в двух разных сборках - хороший способ выстрелить себе в ногу .источник
internal const
или вpublic static readonly
зависимости от желаемой видимости.public const
(например, что-нибудь в стандарте. Каждый раз, когда я работаю с XML, есть Файл пространств имен с кучейpublic const string
.) Но в целом,public const
следует использовать только после правильного рассмотрения последствий.Еще несколько важных вещей, которые следует отметить:
const int a
только для чтения в
источник
ctor
единственного.Это просто дополнение к другим ответам. Я не буду их повторять (сейчас четыре года спустя).
Есть ситуации, когда a
const
и неконстантный имеют разную семантику. Например:распечатывает
True
, тогда как:пишет
False
.Причина в том, что метод
x.Equals
имеет две перегрузки, одна из которых принимаетshort
(System.Int16
), а другая -object
(System.Object
). Теперь вопрос в том, применим ли один или оба к моемуy
аргументу.Когда
y
это константа времени компиляции (литерал),const
становится важным, чтобы существовало неявное преобразование изint
в,short
при условии, чтоint
это константа, и при условии, что компилятор C # проверяет, что ее значение находится в пределах диапазонаshort
( который42
есть). См. Неявные преобразования константных выражений в Спецификации языка C #. Таким образом, обе перегрузки должны быть учтены. ПерегрузкаEquals(short)
предпочтительна (любаяshort
естьobject
, но не всеobject
естьshort
). Такy
что преобразуется вshort
, и эта перегрузка используется. ЗатемEquals
сравнивает дваshort
одинаковых значения, и это даетtrue
.Когда
y
не является константой, неявное преобразование изint
в неshort
существует. Это потому, что в общем случае anint
может быть слишком большим, чтобы помещаться в ashort
. ( Явное преобразование существует, но я не сказалEquals((short)y)
, так что это не имеет значения.) Мы видим, что применяется только одна перегрузка -Equals(object)
одна. Такy
в штучной упаковкеobject
. ЗатемEquals
будет сравнивать aSystem.Int16
с aSystem.Int32
, и поскольку типы времени выполнения даже не согласуются, это даст результатfalse
.Мы заключаем, что в некоторых (редких) случаях изменение
const
члена типа наstatic readonly
поле (или другой способ, когда это возможно) может изменить поведение программы.источник
short x = 42;
законным. Потому что там у вас естьint
, а именно, литерал42
, который неявно превращается вshort x
. Но тогда они могли бы ограничить это только числовыми литералами; однако, они решили также разрешить такие вещи, как,short x = y;
гдеy
определяетсяconst int y = 42;
, и затем они закончили с этим.Следует отметить, что const ограничен типами примитивов / значений (исключение составляют строки)
источник
const
может использоваться и для других типов, за исключением того, что он должен быть инициализирован нулем, что делает его бесполезным :)System.Exception
? :)const
могут быть использованы, являютсяsbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
,double
,decimal
,bool
, плюс любыеenum
типы.const
не может использоваться для других типов значений, таких какDateTime
илиTimeSpan
илиBigInteger
. Он также не может использоваться дляIntPtr
структуры (некоторые считают ее «примитивным»; термин «примитивный тип» в C # сбивает с толку). ↵↵const
Может использоваться для всех типов ссылок . Если тип имеетstring
значение, можно указать любое строковое значение. В противном случае значение должно бытьnull
.const
используяdefault
. Дляstruct
типов это экземпляр со всеми его членами, установленными в значения по умолчанию.Только для чтения : значение может быть изменено через
static
конструктор во время выполнения. Но не через функцию члена.Постоянная : по умолчанию
static
. Значение не может быть изменено из любого места (Ctor, Function, время выполнения и т. Д. Не где).Только чтение : значение может быть изменено через конструктор во время выполнения. Но не через функцию члена.
Вы можете взглянуть на мои свойства репо: C # .
источник
readonly
Ключевое слово отличается отconst
ключевого слова.const
Поле может быть инициализированы только при объявлении поля.readonly
Поле может быть инициализирован либо при объявлении или в конструкторе. Следовательно,readonly
поля могут иметь разные значения в зависимости от используемого конструктора. Кроме того, хотяconst
поле является константой времени компиляции,readonly
поле может использоваться для констант времени выполненияКраткая и понятная ссылка на MSDN здесь
источник
const
иreadonly
похожи, но они не совсем одинаковы.const
Поле является константой времени компиляции, а это означает , что это значение может быть вычислено во время компиляции.readonly
Поле позволяет устанавливать дополнительные сценарии , в которых какой - то код должен быть запущен во время строительства этого типа. После строительстваreadonly
поле не может быть изменено.Например,
const
члены могут использоваться для определения таких членов, как:Так как значения как 3.14 и 0 являются константами времени компиляции. Тем не менее, рассмотрим случай, когда вы определяете тип и хотите предоставить некоторые заранее созданные экземпляры этого типа. Например, вы можете определить класс Color и предоставить «константы» для общих цветов, таких как черный, белый и т. Д. Это невозможно сделать с помощью константных членов, поскольку правые части не являются константами времени компиляции. Это можно сделать с помощью обычных статических членов:
Но тогда ничто не может помешать клиенту Color изменить его, возможно, путем замены значений Black и White. Излишне говорить, что это вызвало бы смятение у других клиентов класса Color. Функция «только для чтения» предназначена для этого сценария.
Просто вводя
readonly
ключевое слово в объявлениях, мы сохраняем гибкую инициализацию, в то же время предотвращая перехват кода клиента.Интересно отметить, что члены-константы всегда являются статическими, тогда как член только для чтения может быть статическим или нет, как обычное поле.
Для этих двух целей можно использовать одно ключевое слово, но это приводит либо к проблемам с версиями, либо к проблемам с производительностью. Предположим на минуту, что мы использовали одно ключевое слово для этого (const), и разработчик написал:
и другой разработчик написал код, который опирался на A:
Теперь, может ли генерируемый код опираться на тот факт, что AC является константой времени компиляции? Т.е. можно ли просто заменить использование AC значением 0? Если вы скажете «да» на это, то это означает, что разработчик A не может изменить способ инициализации AC - это связывает руки разработчика A без разрешения.
Если вы ответите «нет» на этот вопрос, то пропустите важную оптимизацию. Возможно, автор A уверен, что AC всегда будет нулевым. Использование const и readonly позволяет разработчику A указать намерение. Это улучшает поведение при управлении версиями, а также повышает производительность.
источник
Я предпочитаю использовать const всякий раз, когда могу, что, как упоминалось выше, ограничено буквальными выражениями или чем-то, что не требует оценки.
Если я столкнусь с этим ограничением, то вернусь к статическому только для чтения , с одним предупреждением. Я бы обычно использовал открытое статическое свойство с геттером и резервное приватное статическое поле только для чтения, как здесь упоминает Марк .
источник
Ссылка: c-sharpcorner
источник
Статическое поле только для чтения выгодно, когда другим сборкам предоставляется значение, которое может измениться в более поздней версии.
Например, предположим, что сборка
X
предоставляет константу следующим образом:Если сборка
Y
ссылается наX
эту константу и использует ее, значение 2.3 будет встроено в сборкуY
при компиляции. Это означает, что еслиX
позже будет перекомпилирован с константой, установленной в 2.4,Y
все равно будет использоваться старое значение 2.3, пока неY
будет перекомпилировано. Статическое поле только для чтения позволяет избежать этой проблемы.Другой способ взглянуть на это состоит в том, что любое значение, которое может измениться в будущем, не является постоянным по определению и поэтому не должно быть представлено как единое целое.
источник
Const:
только для чтения:
источник
Const : значения переменных const должны определяться вместе с объявлением, и после этого оно не изменится. const неявно статичны, поэтому без создания экземпляра класса мы можем получить к ним доступ. это имеет значение во время компиляции
ReadOnly : значения переменных только для чтения, которые мы можем определить при объявлении, а также при использовании конструктора во время выполнения. Переменные только для чтения не могут получить доступ без экземпляра класса.
Статический только для чтения : значения статических переменных только для чтения, которые мы можем определить при объявлении, а также только через статический конструктор, но не с помощью любого другого конструктора. К этим переменным мы также можем обращаться, не создавая экземпляр класса (как статические переменные).
Статическое чтение только будет лучшим выбором, если мы будем использовать переменные в разных сборках. Пожалуйста, проверьте полную информацию в ссылке ниже
https://www.stum.de/2009/01/14/const-strings-a-very-convenient-way-to-shoot-yourself-in-the-foot/
источник
Существует небольшая разница между полями const и static readonly в C # .Net
const должен быть инициализирован значением во время компиляции.
const по умолчанию является статическим и должен быть инициализирован постоянным значением, которое нельзя изменить позже. Его нельзя использовать со всеми типами данных. Для экс-DateTime. Его нельзя использовать с типом данных DateTime.
readonly может быть объявлен как статический, но не обязательный. Не нужно инициализировать во время объявления. Его значение может быть присвоено или изменено с помощью конструктора один раз. Таким образом, существует возможность один раз изменить значение поля только для чтения (не имеет значения, статическое оно или нет), что невозможно с помощью const.
источник
Константы, как следует из названия, поля, которые не меняются и обычно определяются статически во время компиляции в коде.
Переменные только для чтения - это поля, которые могут изменяться при определенных условиях.
Они могут быть инициализированы при первом объявлении их как константы, но обычно они инициализируются во время конструирования объекта внутри конструктора.
Они не могут быть изменены после инициализации в условиях, указанных выше.
Статическое чтение только для меня кажется плохим выбором, поскольку, если оно статическое и оно никогда не меняется, просто используйте его public const, если оно может измениться, то оно не является константой, а затем, в зависимости от ваших потребностей, вы можете использовать read только или просто обычная переменная.
Также еще одно важное отличие состоит в том, что константа принадлежит классу, а переменная только для чтения принадлежит экземпляру!
источник
Const (определяемый во время компиляции) может быть использован в тех случаях, когда статический readonly не может, например, в операторах switch или конструкторах атрибутов. Это связано с тем, что поля только для чтения разрешаются только во время выполнения, а для некоторых конструкций кода требуется гарантия времени компиляции. Статическая информация только для чтения может быть рассчитана в конструкторе, что часто является важной и полезной вещью. Разница функциональная, как и должно быть их использование на мой взгляд.
С точки зрения распределения памяти, по крайней мере со строками (являющимися ссылочным типом), похоже, нет никакой разницы в том, что оба интернированы и будут ссылаться на один интернированный экземпляр.
Лично у меня по умолчанию статический режим только для чтения, так как он имеет для меня более смысловой и логический смысл, тем более что большинство значений не нужны во время компиляции. И, между прочим, общедоступная статическая информация только для чтения не является чем-то необычным или необычным, как отмечается отмеченным ответом: например,
System.String.Empty
один.источник
Другое различие между объявлением const и static readonly заключается в распределении памяти.
Статическое поле принадлежит типу объекта, а не экземпляру этого типа. В результате, как только на класс ссылаются в первый раз, статическое поле будет «жить» в памяти в течение остального времени, и все экземпляры этого типа будут ссылаться на один и тот же экземпляр статического поля.
С другой стороны, поле const "принадлежит экземпляру типа.
Если память освобождения важнее для вас, предпочтите использовать const . Если скорость, то используйте статическое чтение только .
источник