Подтвердить что ты не робот

Есть ли разница между частными переменными const и private readonly в С#?

Есть ли разница между наличием переменной private const или переменной private static readonly в С# (кроме необходимости присваивать const выражение времени компиляции)?

Поскольку они оба являются частными, связь с другими библиотеками отсутствует. Так это будет иметь какое-то значение? Может ли это сделать разницу в производительности, например? Интернированные строки? Что-нибудь подобное?

4b9b3361

Ответ 1

Ну, вы можете использовать consts в атрибутах, поскольку они существуют как время компиляции. Вы не можете предсказать значение статической переменной readonly, так как .cctor может инициализировать ее из конфигурации и т.д.

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

Повторное интернирование; хотя вы можете сделать это вручную, это чаще всего функция компилятора/времени выполнения литералов; если вы инициализируете поле readonly через литерал:

someField = "abc";

то "abc" будет интернирован. Если вы прочитаете его из config, этого не будет. Поскольку постоянная строка должна быть буквальной, она также будет интернирована, но к ней обращаются по-другому: снова чтение из поля является де-ссылкой, а не ldstr.

Ответ 2

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

  • 'const' должен быть инициализирован там, где они объявлены (во время компиляции), тогда как "readonly" может быть инициализирован там, где он объявлен или внутри конструктора (ar runtime).

Например, const может использоваться в этой ситуации:

public class MathValues
{
  public const double PI = 3.14159;
}

И для чтения было бы лучше:

public class Person
{
    public readonly DateTime birthDate;

    public Person(DateTime birthDate)
    {
        this.birthDate = birthDate;
    }
}

или

public class Person
{
    public readonly DateTime birthDate = new DateTime(1986, 1, 24);
}
  • 'const' является статическим, поэтому он разделяется между всеми экземплярами этого класса и может быть доступен напрямую (например, MathValues.PI), тогда как "readonly" не является статическим. Как следствие, объявление, подобное "static const", является незаконным, поскольку const является статическим, но "static readonly" является законным.

  • 'const' может содержать только интегральный тип (sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool или string), перечисление, или ссылку на нуль (не классы или структуры, потому что они инициализируются во время выполнения, с ключевым словом "новое" ), тогда как "readonly" может содержать сложные типы, структуры или классы (используя новое ключевое слово при инициализации), но не может содержать перечисления

Ответ 3

Что-то, что нужно помнить о константах, они фактически хранятся в вашем исполняемом файле, поэтому объявление многих из них увеличит размер исполняемого файла.

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

Ответ 4

В использовании? На самом деле, нет. Consts оцениваются во время компиляции, тогда как readonly оцениваются во время выполнения. Вы также можете назначить переменную readonly значение в конструкторе.

Ответ 5

Вот различия между С#.NET const, readonly и static readonly полями (из в этой статье).

Константы

  • Статический по умолчанию
  • Должно иметь значение времени компиляции (т.е. вы можете иметь "A" + "B", но не можете иметь вызовы методов)
  • Может использоваться в атрибутах
  • Скопируются в каждую сборку, которая их использует (каждая сборка получает локальную копию значений)
  • Может быть объявлено внутри функций

поля экземпляра Readonly:

  • Оцениваются при создании экземпляра
  • Должно быть установлено значение с помощью конструктора времени

Статические поля только для чтения:

  • Оцениваются, когда выполнение кода попадает в ссылку на класс (то есть: создается новый экземпляр или выполняется статический метод)
  • Должно быть оценено значение по времени, когда статический конструктор выполнен
  • Вы действительно не хотите ставить ThreadStaticAttribute на них (поскольку статический конструктор будет выполняться только в одном потоке, и он установит значение для своего потока, все остальные потоки будут иметь это значение неинициализированным)

Ответ 6

Значительная разница между полями const и readonly в С#.Net

const по умолчанию статический и должен быть инициализирован с постоянным значением, которое впоследствии не может быть изменено. Изменение значения также не допускается в конструкторах. Он не может использоваться со всеми типами данных. Для ex-DateTime. Он не может использоваться с типом данных DateTime.

public const DateTime dt = DateTime.Today;  //throws compilation error
public const string Name = string.Empty;    //throws compilation error
public readonly string Name = string.Empty; //No error, legal

readonly может быть объявлен как статический, но необязательный. Не нужно инициализировать во время объявления. Его значение может быть назначено или изменено с помощью конструктора. Таким образом, он дает преимущество при использовании в качестве члена класса экземпляра. Два разных экземпляра могут иметь другое значение поля readonly. Для ex -

class A
{
    public readonly int Id;

    public A(int i)
    {
        Id = i;
    }
}

Затем поле readonly может быть инициализировано мгновенными конкретными значениями следующим образом:

A objOne = new A(5);
A objTwo = new A(10);

Здесь экземпляр objOne будет иметь значение поля readonly как 5, а objTwo - 10. Это невозможно при использовании const.

Ответ 7

Еще одна вещь. Я не видел этого в комментариях выше, хотя я, возможно, пропустил это. Вы не можете создать постоянный массив.

private const int[] values = new int[] { 1, 2, 3 };

Но вы можете создать его с помощью статического поля readonly.

private static readonly int[] values = new int[] { 1, 2, 3 };

Итак, если вам нужна константа массива, такая как список допустимых значений, и перечисление не подходит, то статический readonly - единственный способ пойти. Например, если массив имеет нулевые целые числа, например:

private static readonly int?[] values = new int?[] { null, 1, 2, 3 };

Не могу сделать это с константой, может я?

Ответ 8

Поля Readonly могут быть инициализированы либо в объявлении, либо в конструкторе класса. Поэтому поля readonly могут иметь разные значения в зависимости от используемого конструктора.

Элемент readonly также может быть использован для констант времени выполнения, как в следующем примере:

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

Поля readonly не являются неявно статическими, и поэтому статическое ключевое слово может (должно) быть применено к полю readonly явно, если это необходимо. Это недопустимо для константных полей, которые неявно статичны.

Члены Readonly могут содержать сложные объекты, используя новое ключевое слово при инициализации.

Ответ 9

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

В статическом случае readonly, содержащемуся классу разрешено изменять его только

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

Также доступны поля readonly экземпляра.

Помните, что для ссылочных типов в обоих случаях (статический и экземпляр) модификатор readonly только запрещает вам назначать новую ссылку на это поле. Он специально не делает неизменным объект, на который указывает ссылка.

class Program

{

  public static readonly Test test = new Test();

  static void Main(string[] args)

  {

     test.Name = "Program";

     test = new Test(); // Error: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)

  }

}

class Test

{

   public string Name;

}

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

- в объявлении переменной (через инициализатор переменной).

- в статическом конструкторе (конструкторы экземпляра, если он не статичен).


Ключевое слово Const в С#.NET

Пример: public const string abc = "xyz"; Инициализируется только при объявлении. Значение оценивается во время компиляции и не может быть изменено во время выполнения. Попытка изменить его вызовет ошибку компиляции. Констант уже является статичным. Поскольку классы и структуры инициализируются во время выполнения с помощью нового ключевого слова, вы не можете установить константу в класс или структуру. Но это должен быть один из интегральных типов. Ключевое слово Readonly в С#.NET

Пример: public readonly string abc; Может быть инициализирован в коде декларации или в коде consturctor. Значение оценивается во время выполнения. Может быть объявлен как статический или атрибут уровня экземпляра. Поле только для чтения может содержать сложный объект, используя ключевое слово new во время выполнения.