Модификатор Const в C# делает поля или локальные переменные постоянными. К полям в C# применяется только чтение, значение остается постоянным после инициализации.

Static ReadOnly делает членом класса поля ReadOnly. (Можно получить доступ через имя класса)

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

10 основных различий между полями Const и Readonly в C#:

Поле С# Const или локальное:

Мы будем использовать ключевое слово «const» для объявления константных полей или локальных переменных в C#.

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

Public class Program
        {
           const int fieldConstant = 10; //Field

           static void Main(string[] args)
           {
             const int X = 10, Y = 50; //Correct //Local Variable
             const int Z = X + Y;      //Correct
             const int A = X + GettheValue(); // Error
           } 
           public static int GettheValue()
           {
             const int localx=10;
             return 10;
           }
        }

Первые две строки будут работать без каких-либо ошибок, потому что значения полей X, Y, Z оцениваются во время самой компиляции.

Но в 3-й строке мы объявили переменную «A» как константу и пытаемся оценить ее значение во время выполнения с помощью метода GettheValue().

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

Поле в C# — это переменная, объявленная непосредственно в классе или структуре

В приведенном выше примере fieldConstant является полем, поскольку оно объявлено непосредственно внутри класса программы.

И мы можем объявить локальные переменные как const, как показано выше в методе GetTheValue().

Следующие встроенные типы значений могут быть объявлены как константы: int, long, char, float, double, decimal, bool, byte, short, строковая переменная как const.

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

const string constantString = "Hi Iam Constant"; 
//Correct const Program program = new Program(); //Error const 
Program program1 = null; //Correct

Вы не можете объявить константную переменную как статическую, потому что константные поля по умолчанию считаются статическими членами.

ReadonlyConstant r1=new ReadonlyConstant();
// Please see the below code for class declaration 
Console.WriteLine(r1.ynumber); //Error 
Console.WriteLine(ReadonlyConstant.ynumber);//Correct

Поскольку константная переменная по умолчанию статическая, вы не можете получить к ней доступ из экземпляра класса. И мы не можем передавать константные значения в качестве параметров ref или out.

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

Мы можем объявлять поля как доступные только для чтения в C#, а не как локальные переменные.

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

public class ReadonlyConstant
    {
        
        public const int numberOfDays = 7; //Field
        public readonly double PI=3.14;             //inline intialization
        
        public readonly int znumber;
        public readonly List<int> readonlyList;

        public ReadonlyConstant()
        {
            znumber= 50;//Constructor initialization            
        }

        public ReadonlyConstant(int x)
        {
             znumber=100;
        }
        
        public NormalMethod()
        {
            //readonly int i=0; This is wrong
        }
    }

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

Пожалуйста, прочтите дальнейшую статью о поле только для чтения, чтобы лучше понять его.

Любопытный случай с полем Readonly в C#

Теперь мы рассмотрим различия между константными полями и полями только для чтения. Как упоминалось во втором пункте, для константных полей не выделяется память, а значение непосредственно встроено в код IL. см. изображение кода IL ниже. (Несколько различий объяснены в сообщении выше)

Я использовал инструмент resharper, чтобы увидеть код промежуточного языка (IL) приведенного выше примера программы (ReadonlyConstant.cs)

Как видите, IL-код константного поля numberOfdays (7) непосредственно встроен в IL-код. Где поле piValue, доступное только для чтения, отображается как piValue, т. е. значение может быть получено во время выполнения.

Это приводит к проблемам с версиями.

Проблема управления версиями поля Const в С#:

Я скомпилировал приведенную выше примерную программу как библиотеку классов (A) и использовал ее в другом проекте (в B) в качестве ссылки. Теперь посмотрите сгенерированный IL-код проекта B.

И даже в коде IL проекта B значение поля const numberofdays встроено в код IL. Теперь проблема в том, что в источнике (в библиотеке ReadonlyConstant.cs) значение поля const (numberOfdays) изменилось на 5, скомпилировано и сгенерировано новая dll.

Но это новое значение поля const не влияет на проект B до тех пор, пока мы не скомпилируем проект. После компиляции новое значение поля const будет внедрено в IL-код проекта B.

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

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

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

public class ReadonlyStatic
{
   public static readonly string x = "Hi";
   public static readonly string y;

   public ReadonlyStatic()
   {
     //y = "Hello"; This is wrong
   }

   static ReadonlyStatic()
   {
      y = "Hello";
   }
}

Теперь мы можем использовать его как константу во всем классе, чтобы преодолеть проблему версии dll с константными переменными. Могут быть некоторые проблемы с производительностью, но нет необходимости создавать целевой проект, поскольку значение можно получить во время выполнения.

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

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

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

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

Только для чтения Может быть назначено во время объявления или конструктора

Статический Только для чтения Может быть назначен во время объявления или статического конструктора

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

Статическое значение только для чтения будет постоянным после инициализации

Когда использовать Const и когда использовать только чтение в C#

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

Например, количество дней в неделе равно 7. Это всегда постоянное значение.

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

Как значение поля const, встроенное в IL. Используйте модификатор const для абсолютных констант, чтобы повысить производительность.

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

Надеюсь, вы понимаете ключевые различия между модификаторами const и readonly в C#.

Если это так, поделитесь с друзьями, и если у вас есть какие-либо сомнения, пожалуйста, не стесняйтесь комментировать ниже.

Удачного кодирования….!

Подождите, прежде чем уйти. почему вы не можете подписаться на меня в твиттере или стать другом в Facebook, googlePlus или linkedn, чтобы связаться со мной.

Первоначально опубликовано на www.arungudelli.com 16 сентября 2017 г.