Przejdź do głównej zawartości

[C#] Czym się różni const od readonly?


Między const a readonly instnieje kilka zasadniczych różnic:
  • wartosć pola zdefiniowanego jako const należy ustalić w momencie jego deklaracji, zaś wartość pola zdefiniowanego jako readonly możemy ustawić w konstruktorze
  • const jest deklarowana jako static, jednak napisanie wprost static const powoduje błąd kompilacji
  • wartość pól const jest znana w czasie kompilacji (compile time), zaś wartość pól readonly w czasie wykonywania programu (run time)
  • w czasie kompilacji użycia pól z modyfikatorem const są podmieniane na ich wartości przez kompilator, zaś readonly nie
Przyjrzyjmy się jak zachowują się pola z modyfikatorem const:

    public class ConstExample
    {
        private const int A; //błąd kompilacji - należy od razu przypisać wartość
        private const string TEXT = "witam"; //ok
        private static const int B = 5; //błąd kompilacji - nie możemy wprost oznaczyć jako static

        public ConstExample()
        {
            A = 3; //błąd kompilacji - w konstruktorze nie można zmieniać wartości const
        }

        public void SomeMethod()
        {
            var testObject = new ConstExample();
            Console.WriteLine(testObject.TEXT); //błąd kompilacji - stała TEXT jest static
            Console.WriteLine(ConstExample.TEXT); //ok
        }
    }

Teraz przyjrzyjmy się modyfikatorowi readonly:

    public class ReadonlyExample
    {
        private readonly int A; //ok
        private readonly string TEXT = "witam"; //ok
        public static readonly int B = 5; //ok
        public readonly int C; //ok

        public ReadonlyExample()
        {
            A = 3; //ok
            //uwaga - nie przypisujemy wartości do C
        }

        public void SomeMethod()
        {
            var testObject = new ReadonlyExample();
            Console.WriteLine(testObject.TEXT); //ok
            Console.WriteLine(ReadonlyExample.TEXT); //błąd - wartosc TEXT nie jest static
            Console.WriteLine(ReadonlyExample.B); //ok - sami napisaliśmy, że jest static
            Console.WriteLine(testObject.C); //wypisze się domyślna wartość - w tym przypadku 0
        }
    }

Ustaliliśmy wcześniej, że kompilator podmienia użycia pól const na ich wartości w czasie kompilacji. Można to sobie wyobrazić w ten sposób:

Tak wygląda nasz kod:

    public class Consts
    {
        public const int ConstValue = 100;
        public static readonly int ReadonlyValue = 200;
    }

    public class Program
    {
        public void Run()
        {
            Console.WriteLine(Consts.ConstValue);
            Console.WriteLine(Consts.ReadonlyValue);
        }
    }

A tak wygląda nasz kod skompilowany do Intermediate Language (jest to oczywiście uproszczenie):

    public class Consts
    {
        public const int ConstValue = 100;
        public static readonly int ReadonlyValue = 200;
    }

    public class Program
    {
        public void Run()
        {
            Console.WriteLine(100);
            Console.WriteLine(Consts.ReadonlyValue);
        }
    }

Komentarze