C # basic knowledge point-difference between Readonly and Const,

Source: Internet
Author: User
Tags mscorlib

C # basic knowledge point-difference between Readonly and Const,

C # basic knowledge point-difference between Readonly and Const

What are static constants (Const) and Dynamic Constants (Readonly)

First, explain what is a static constant (Const) and what is a dynamic constant (Readonly ).

A static constant (Const) is a constant that the compiler parses during compilation and replaces the value of the constant with the value of the initialization.

The value of a dynamic constant (Readonly) is obtained at the moment of running. during compilation, it is marked as a read-only constant instead of a constant value, in this way, Dynamic Constants do not need to be initialized during declaration, but can be delayed to initialization in the constructor.

Differences between static constants (Const) and Dynamic Constants (Readonly)

Static Constant (Compile-time Constant)

Dynamic Constant (Runtime Constant)

Definition

You must set the constant value when declaring.

You do not need to set constant values when declaring them. You can set them in the constructor of the class.

Type restrictions

Only the primitive type, enumeration type, or string type can be modified.

No limit. You can use it to define constants of any type.

For class objects

For all class objects, the constant value is the same.

For different objects of a class, the constant value can be different.

Memory consumption

None.

To allocate memory, save the constant entity.

Summary

The performance is slightly higher and there is no memory overhead, but there are many restrictions and they are not flexible.

Flexible and convenient, but with low performance and memory overhead.

Const-modified constants must be initialized during Declaration; Readonly-modified constants can be delayed until the constructor is initialized.

Const constants can be declared in the class or in the function body, but Static Readonly constants can only be declared in the class. Const is a Static constant, so it itself is Static. Therefore, you cannot manually add a Static modifier for Const.

Const modified constants are parsed during compilation. That is, after compilation by the compiler, the actual values corresponding to the Const variable will be used to reference the Const variable in the code; readonly modified constants are delayed until running.

For example:

Public static readonly int NumberA = NumberB * 10;

Public static readonly int NumberB = 10;

Public const int NumberC = NumberD * 10;

Public const int NumberD = 10;

Static void Main (string [] args)

{

Console. WriteLine ("NumberA is {0}, NumberB is {1}.", NumberA, NumberB); // NumberA is 0, NumberB is 10.

Console. WriteLine ("NumberC is {0}, NumberD is {1}.", NumberC, NumberD); // NumberC is 100, NumberD is 10.

Console. ReadKey ();

}

The above is a syntax application. In terms of actual usage, there are still some subtle changes that are usually hard to find.

For example:

In the Assembly DoTestConst. dll, there is a class MyClass that defines a public static variable Count.

Public static class MyClass

{

Public const int Count = 10;

}

Then, DoTestConst. dll is referenced in another application and called as follows in the Code:

Public static void Main (string [] args)

{

Console. WriteLine (DoTestConst. MyClass. Count); // output 10

Console. ReadKey ();

}

There is no doubt that the code is very simple and 10 is output directly.

Next, update the Count value of MyClass to 20, recompile DoTestConst. dll, and update it to the directory where the application is located. Be sure not to compile the application. At this time, the output result should be 20 as expected, but it is still 10. Why?

This is the special feature of Const. Check the generated IL and the IL code (assuming that the value of Count is 10 at this time)

IL_0000: nop

IL_0001: ldc. i4.s 10

IL_0003: call void [mscorlib] System. Console: WriteLine (int32)

The red code clearly indicates that 10 is loaded directly without any type of loading and the corresponding variable is obtained. That is to say, DoTestConst is not loaded at runtime. dll, does it mean there is no DoTestConst. can dll be run? The answer is yes. Deleting DoTestConst. dll can also run. Is it strange? This explains why the new value is not called after the value of the Const variable is updated in the previous experiment, because the program will not load DoTestConst. dll during running. So where does the value 10 come from? In fact, CLR performs special processing on the Const variable, namely embedding the Const value directly in the generated IL code and will not load it from the dll during execution. This also brings about a Bug that is not easy to detect. Therefore, when referencing the Const variable of another assembly, you must consider the version update issue, to solve this problem, it is okay to compile the called application again. However, when the actual program is deployed and updated, only a few files may be updated. In this case, you must use the Readonly keyword to solve this problem.

Next, let's look at the Readonly version:

Public static class MyClass

{

Public static readonly int Count = 10;

}

The caller's Code remains unchanged. Then, let's look at the generated IL code:

IL_0000: nop

IL_0001: lds1_int32 [DoTestConst] DoTestConst. MyClass: Count

IL_0006: call void [mscorlib] System. Console: WriteLine (int32)

Obviously, the loading code has changed. A very common ldsfld action requests the Count variable of DoTestConst. MyClass by forcibly loading DoTestConst. Therefore, after the Count value is updated and re-compiled, the calling program is not compiled, and the new value is displayed after execution. If you delete DoTestConst. dll, exceptions such as dll cannot be found. This fully demonstrates that the variables defined for Readonly are loaded at runtime.

Dynamic Constants (Readonly) cannot be changed after being assigned values

The ReadOnly variable is a runtime variable, which cannot be changed after being assigned a value for the first time during the runtime. "Unchangeable" is divided into two meanings:

For value type variables, the value itself cannot be changed (Readonly, read-only)

For reference type variables, the reference itself (equivalent to a pointer) cannot be changed.

Value Type variables:

Public class Student

{

Public readonly int Age;

Public Student (int age)

{

This. Age = age;

}

}

Student's instance Age cannot be changed after being assigned a value in the constructor. The following code will not be compiled:

Student student = new Student (20 );

Student. Age = 21; // error message: you cannot assign values to read-only fields (except in constructors or variable Initiators)

Reference type variables:

Public class Student

{

Public int Age; // note that the Age here does not have the readonly modifier.

Public Student (int age)

{

This. Age = age;

}

}

Public class School

{

Public readonly Student;

Public School (Student student)

{

This. Student = student;

}

}

The Student of the School instance is a variable of reference type. After a value is assigned, the variable cannot point to any other Student instance. Therefore, the following code will not compile and pass:

School school = new School (new Student (10 ));

School. Student = new Student (20); // error message: the read-only field cannot be assigned a value (except in the constructor or variable initiator)

The reference itself cannot be changed, but the reference says that the value of the instance to which it points can be changed. Therefore, the following code can be compiled:

School school = new School (new Student (10 ));

School. Student. Age = 20;

In the constructor, we can assign values to constants modified by Readonly multiple times. For example:

Public class Student

{

Public readonly int Age = 20; // Note: The Initialization is actually part of the constructor. It is actually a syntactic sugar.

Public Student (int age)

{

This. Age = age;

This. Age = 25;

This. Age = 30;

}

}

Summary

The maximum difference between Const and Readonly (except syntax)

The Const variable is embedded in the IL code. It is loaded well during compilation and does not depend on external dll (this is why the Const cannot assign values in the Const method ). Const is prone to version inconsistencies when the Assembly is updated.

Readonly variables are loaded at runtime. You need to request to load the dll and obtain the latest value each time. After a value is assigned to the reference type, the reference itself cannot be changed, but the value of the instance to which the reference points can be changed. In the constructor, we can assign values to Readonly multiple times.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.