简体   繁体   中英

const and readonly keyword in C#

I have read about the const and readonly keyowrds in C#. One of the difference between these keywords is that the value of the const is resolved at compile time while readonly keyword is resolved at run time. Though I didn't get chance to implement them in any of my projects. So I thought of giving it a try. I created mylibrary which I would use in my other project. The code in mylibrary is as following

 namespace MyLibrary
 {
  public class Class1
  {
    public static readonly string MyVar = "Vikram";
    //public readonly string MyVar;
    //public Class1()
    //{
    //    MyVar = "Test";
    //}
  }
}

Now I would use this library as reference in my other console project as following

class Program
{
    static void Main(string[] args)
    {
        //MyLibrary.Class1 class1 = new MyLibrary.Class1();
        Console.WriteLine(MyLibrary.Class1.MyVar); // output is vikram
        Console.ReadLine();
        Console.WriteLine(MyLibrary.Class1.MyVar); // changed to Test but still op as  vikram
        Console.ReadLine();
    }
}

Now between these two writeline's I will change the value of "MyVar" in my library and recompile it, according to readonly's concept it should get reflected in the console project without recompiling my main project.

Please correct me if I my understanding of the readonly keyword is wrong.

PS I have been through the answers of this link. In one of the answers the following is being mentioned

in the case of the readonly value, it is like a ref to a memory location. The value is not baked into AssemblyB's IL. This means that if the memory location is updated, Assembly B gets the new value without recompilation. So if I_RO_VALUE is updated to 30, you only need to build AssemblyA. All clients do not need to be recompiled.

Can anyone please explain what does the bold line exactly means. I think this is what I am doing in my example.

Your understanding is right, with the exception that you cannot change an assembly that is already loaded. You have to restart the program.

I think you can change a readonly field with reflection. That makes it easier to test this.

Btw, the value of a readonly field must be a runtime value because you can put an arbitrary initializer on it. No way that could be hard-coded by the C# compiler because it cannot know the runtime value statically.

I think that you don't fully understand the meaning of the readonly modifier. Check this reference for information about it.

Please note that the following line:

public static readonly string MyVar = "Vikram";

doesn't mean that each time that you refer to MyVar it's value be re-evaluated.
It just means that once the value of MyVar is set, it won't be changed again, making it readonly for any further use.

eg, the following lines:

public class Class1
{
    public static readonly string MyVar;

    public Class1()
    {
        MyVar = SomeCalculation();
    }

    Console.WriteLine(MyLibrary.Class1.MyVar);
    Console.WriteLine(MyLibrary.Class1.MyVar);
}

will trigger SomeCalculation() only once !

Read Only : Memory is allocated at run time, value is initialised at the run time.

Constant : It uses "const" key word. Value is assigned at the time of declaration. The value will be constant throughout the program. eg. const int i=5;

you only need to build AssemblyA. All clients do not need to be recompiled.

There is assembly A and assembly B . Assembly A has the const expression in it somewhere, like:

public const int number = 10;

If this number is used within assembly B , the compiler will simply put the 'raw' value of the number variable inside the assembly B s metadata. If number is changed in A , nothing will be changed in B . To make the embedded value change in the assembly B , B has to be recompiled too. One of the benefit of this behavioral, there is no need to load the assembly A to use assembly B .

However, in case of readonly , in this perspective it works like every other (instance|class) fields. It doesn't work like the static way of const (const is considered to be only class level variable, never instance variable)

I have written an article after reading a bit about the keywords here on my blog

Some excerpts from the blog Constants

  • provide the value to the const field when it is defined.
  • the compiler then saves the constant's value in the assembly's metadata
  • constants are always considered static members, not instance members.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM