Есть ли разница между частными переменными const и частными переменными только для чтения в C #?

StackOverflow https://stackoverflow.com/questions/410723

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

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

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

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

someField = "abc";

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

Другие советы

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

  • 'const' должны быть инициализированы там, где они объявлены (во время компиляции), тогда как 'только для чтения' может быть инициализировано там, где оно объявлено, или внутри конструктора (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), тогда как 'только для чтения' не является статическим.Как следствие, объявление типа 'static const' является незаконным, потому что const является статическим, но 'static readonly' является законным

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

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

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

Вот различия между C # .NET постоянный, только для чтения и статический доступ только для чтения поля (из эта статья).

Константы:

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

Поля экземпляра только для чтения:

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

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

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

Существует заметная разница между постоянный и только для чтения поля в C#.Net

const по умолчанию является статическим и должен быть инициализирован постоянным значением, которое впоследствии не может быть изменено.Изменение значения также не допускается в конструкторах.Он не может быть использован со всеми типами данных.Например, дата- время.Он не может быть использован с типом данных 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

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

class A
{
    public readonly int Id;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 никогда не может быть изменен и должен быть инициализирован константой времени компиляции.Чтобы немного расширить статический регистр, доступный только для чтения, содержащий класс может только изменять его:

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

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


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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top