Какая разница между константой, readonly и get в статическом классе

У меня есть вопрос. В последнее время я поймал себя на использовании трех разных строк кода, которые при ближайшем рассмотрении смотрят и чувствуют то же самое.

public static class constant
{
    public static readonly int val1 = 5;
    public const int val2 = 5;
    public static int val3 { get { return 5; } }
}

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

также как дополнительный вопрос в visual studio, почему все они представлены по-разному в intellisense?

enter image description here

Ответы

Ответ 1

Член, объявленный как readonly, дает возможность быть измененным в (статическом) конструкторе класса, в то время как член const не может быть изменен во время выполнения.

Объявление поля как const делает его автоматически статическим, цитируя из §10.3.7:

Когда поле, метод, свойство, событие, оператор или конструктор Объявление содержит статический модификатор, объявляет статический член. Кроме того, объявление константы или типа неявно объявляет статический член.

Третий - это просто свойство только для чтения, которое всегда возвращается 5.

Вы никогда не должны использовать такое свойство и, если возможно, предпочитаете константные члены, чтобы позволить компилятору и/или дрожанию выполнять их оптимизацию и помогать другим людям, читающим ваш код (это свойство является для меня WTF), Статический член readonly должен использоваться, если требуется постоянное значение, инициализированное во время запуска программы (например, количество ядер ядра).

Это отличный пример из спецификаций С# (§10.5.2.1):

Статическое поле readonly полезно, когда символическое имя константы желательно, но когда тип значения не разрешен в const, или когда значение не может быть вычислено в время компиляции. В примере

public class Color
{
    public static readonly Color Black = new Color(0, 0, 0);
    public static readonly Color White = new Color(255, 255, 255);
    public static readonly Color Red = new Color(255, 0, 0);
    public static readonly Color Green = new Color(0, 255, 0);
    public static readonly Color Blue = new Color(0, 0, 255);
    private byte red, green, blue;
    public Color(byte r, byte g, byte b) {
        red = r;
        green = g;
        blue = b;
    }
}

Члены Black, White, Red, Green и Blue не могут быть объявлены как const, потому что их значения не могут быть вычислены во время компиляции. Однако, объявляя их статическими readonly, вместо этого имеет одинаковую эффект.

И еще одно отличие (§10.5.2.2):

Поля констант и readonly имеют разные бинарные версии семантика. Когда выражение ссылается на константу, значение константа получается во время компиляции, но когда выражение ссылается на поле readonly, значение поля не получается до времени выполнения.

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

Ответ 2

Статический readonly может быть назначен на constroctor, тогда как const не может. Кроме того, получателю не нужно возвращать постоянное значение, значение van является частным членом, которое может быть изменено в другой части класса или быть вычисленным значением.

Из readonly (ссылка С#)

Ключевое слово readonly отличается от ключевого слова const. A const поле может быть инициализировано только при объявлении поля. поле readonly может быть инициализировано либо в декларации, либо в конструктор. Поэтому поля readonly могут иметь разные значения в зависимости от используемого конструктора. Кроме того, хотя поле const является константа времени компиляции, поле readonly может использоваться для времени выполнения как в следующем примере:

public static readonly uint timeStamp = (uint)DateTime.Now.Ticks;

Ключевое слово readonly - это модификатор, который можно использовать для полей. Когда объявление поля включает модификатор readonly, присвоения поля, введенные декларацией, могут возникать только как часть объявления или в конструкторе того же класса.

Из const (ссылка С#)

Ключевое слово const используется для изменения объявления поля или локального переменная. Он указывает, что значение поля или локального переменная является постоянной, что означает, что она не может быть изменена.

Кроме того, они различаются в intellisense, поскольку они являются разными объектами времени компиляции

Ответ 3

Вы должны использовать поля const ant, когда можете, но это работает только для примитивных типов.

Если вам нужен пользовательский тип (скажем, ваш собственный класс или структура), вы должны использовать public static property.

Открытые поля используются только в структурах, и я не могу вспомнить случай, когда я видел какое-либо общедоступное статическое поле readonly.

Ответ 4

когда вы используете const или readonly в своих определениях полей. Спецификатор const может использоваться с типами primitive data и только для строк. При использовании значение, назначенное для поля const, вставляется непосредственно во все его ссылки в сгенерированном IL-коде. Это справедливо и для других сборок. Другие сборки, относящиеся к этому полю const, скомпилированы так, как если бы они непосредственно использовали значение самого значения. Поля readonly - это постоянные времени выполнения. Они занимают какое-то место в памяти, а ссылки на них разрешаются во время выполнения, как если бы мы ссылались на обычную переменную. На самом деле это переменные, которые напоминают константы.

const:

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

  • Не может быть статическим.
  • Значение оценивается во время компиляции.
  • Initiailized только при объявлении.

readonly:

  • Может быть либо на уровне экземпляра, либо на статическом уровне.
  • Значение оценивается во время выполнения.
  • Может быть инициализирован в объявлении или кодом в конструкторе.

Ответ 5

Const - выражение, вычисляемое во время компиляции. Компилятор может вставлять значение непосредственно во все используемые им места. Статическое только чтение будет оцениваться только во время выполнения и полезно, если вы считаете, что значение может быть изменено позже, поскольку сборки, скомпилированные против вас, не будут иметь встроенного значения статического чтения, что может случиться с константой. Обратите внимание на некоторые значения, такие как DateTime.Now не может быть сохранен в константе, потому что это оценка свойства, которое должно выполняться во время выполнения. Вы можете использовать только статическое чтение, и оно будет похоже на константу, но оно будет фиксировать значение во время выполнения.

Последний - это свойство, которое может сделать гораздо больше, чем просто вернуть значение. Это может быть результат вызова веб-службы или комплексного расчета. Обратите внимание, что код в свойстве может получить inlined компилятором.

Какой из них вы используете, зависит от семантики, которую вы хотите.

Ответ 6

Привет, вы найдете ответ на свои вопросы в этом сообщении:

Статический readonly vs const

Вы также можете проверить код IL и попытаться сравнить результат по себе.

Ответ 7

Я просто объясню ваш первый вопрос.

Const; члены должны получать начальные значения во время компиляции, а затем их нельзя изменить. Статический readonly; не нужно назначать значения членов для инициализации, а затем назначаться. После назначения нельзя изменить один раз.

Статические члены readonly могут быть доступны из класса, к которому они принадлежат, и значение может быть назначено. Первое назначение значения, которому должно быть назначено значение членов, должно быть выполнено или статический конструктор должен быть сделан в транзакции.