разница - readonly c# описание




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

Const: Const - это не что иное, как «постоянная», переменная, значение которой является константой, но во время компиляции. И обязательно присвоить ему значение. По умолчанию константа является статической, и мы не можем изменить значение переменной const во всей программе.

Статическое ReadOnly: значение переменной Static Readonly может быть назначено во время выполнения или назначено во время компиляции и изменено во время выполнения. Но значение этой переменной может быть изменено только в статическом конструкторе. И нельзя изменить дальше. Он может меняться только один раз во время выполнения

Ссылка: c-sharpcorner

Я читал о const и static readonly полях static readonly . У нас есть некоторые классы, которые содержат только постоянные значения. Используется для разных вещей в нашей системе. Поэтому мне интересно, правильное ли мое наблюдение:

Должны ли эти постоянные значения всегда static readonly для всего, что static readonly ? И использовать только const для внутренних / защищенных / частных значений?

Что вы порекомендуете? Должен ли я, возможно, даже не использовать static readonly поля static readonly , а скорее использовать свойства, возможно?


Const:

  1. ценность должна быть указана после объявления
  2. константа времени компиляции

только для чтения:

  1. значение может быть задано при объявлении или во время выполнения с использованием конструкторов. Значение может варьироваться в зависимости от используемого конструктора.
  2. постоянная времени выполнения

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

Краткая и понятная ссылка MSDN здесь


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

Только для чтения переменные - это поля, которые могут меняться при определенных условиях.

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

Они не могут быть изменены после инициализации в указанных выше условиях.

Статическое только для чтения звучит как плохой выбор для меня, поскольку, если он статичен и он никогда не изменяется, просто используйте его public const, если он может измениться, то он не является константой, а затем, в зависимости от ваших потребностей, вы можете либо использовать read - или просто регулярная переменная.

Кроме того, еще одно важное отличие состоит в том, что константа принадлежит классу, а переменная, доступная только для чтения, принадлежит экземпляру!


Некоторые другие вещи

const int a

  • должен быть инициализирован
  • инициализация должна быть во время компиляции

readonly int a

  • может использовать значение по умолчанию, без инициализации
  • инициализация может быть во время выполнения

Следует отметить, что константа ограничена примитивными / значениями типов (исключение - это строки)


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

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

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

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

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


Это просто дополнение к другим ответам. Я не буду повторять их (сейчас четыре года спустя).

Бывают ситуации, когда const и не константа имеют разную семантику. Например:

const int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

распечатывается True , тогда как:

static readonly int y = 42;

static void Main()
{
  short x = 42;
  Console.WriteLine(x.Equals(y));
}

пишет 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 . Это потому, что в целом int может быть слишком огромным, чтобы вписаться в short . ( Явное преобразование действительно существует, но я не сказал Equals((short)y) , так что это не имеет значения.) Мы видим, что применяется только одна перегрузка - Equals(object) . Таким образом, y помещается в поле для object . Затем Equals будет сравнивать System.Int16 с System.Int32 , и поскольку типы времени выполнения даже не согласуются, это приведет к false .

Мы заключаем, что в некоторых (редких) случаях изменение члена типа const в static readonly поле static readonly (или, наоборот, когда это возможно) может изменить поведение программы.


const и readonly похожи, но они не совсем то же самое.

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

Например, члены const могут использоваться для определения таких членов, как:

struct Test
{
    public const double Pi = 3.14;
    public const int Zero = 0;
}

Так как значения, такие как 3.14 и 0, являются константами времени компиляции. Однако рассмотрите случай, когда вы определяете тип и хотите предоставить некоторые предварительные экземпляры. Например, вы можете определить класс «Цвет» и предоставить «константы» для обычных цветов, таких как «Черный», «Белый» и т. Д. Это невозможно сделать с помощью константных членов, поскольку правые части не являются константами времени компиляции. Это можно сделать с помощью обычных статических элементов:

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

    public Color(byte r, byte g, byte b) => (red, green, blue) = (r, g, b);
}

Но тогда нет ничего, что могло бы заставить клиента «Цвет» уклониться от него, возможно, заменив значения «черный и белый». Излишне говорить, что это вызовет ужас для других клиентов класса Color. Функция «только для чтения» рассматривает этот сценарий.

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

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, green, blue) = (r, g, b);
}

Интересно отметить, что константные члены всегда статичны, тогда как член readonly может быть либо статичным, либо нет, как обычное поле.

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

public class A
{
    public static const C = 0;
}

и другой разработчик написал код, который основывался на A:

public class B
{
    static void Main() => Console.WriteLine(A.C);
}

Теперь, может ли генерируемый код полагаться на то, что AC является константой времени компиляции? Т.е., может ли использование переменного тока просто заменить на значение 0? Если вы говорите «да», то это означает, что разработчик A не может изменить способ инициализации AC - это связывает руки разработчика A без разрешения.

Если вы скажете «нет» на этот вопрос, тогда будет пропущена важная оптимизация. Возможно, автор A положителен, что AC всегда будет равен нулю. Использование как const, так и readonly позволяет разработчику A указать намерение. Это улучшает поведение версий, а также повышает производительность.


public static readonly поля public static readonly немного необычны; public static свойства (только с get ) будут более распространены (возможно, поддерживаются private static readonly полем private static readonly ).

значения const сожжены непосредственно на сайте call-сайта; это двойное очертание:

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

Если значение никогда не изменится, то const будет нормально - Zero т. Д. Сделают разумные константы; p Кроме этого, static свойства более распространены.





constants