I. The dispute between Const and ReadOnly
You must have written a const, must have used ReadOnly, but talk about the difference between the two, and say when to use the const, when with the ReadOnly, you can clearly organized to say a 123? The reason why Const and readonly are so controversial is that there is an "immutable" nature of each other, and for both, we need to be concerned that
when does it start to change? What is immutable ?This leads us to the topic we are going to discuss below.
Two. When does it start to become immutable?
Let's start by throwing a conclusion.
Const is immutable at any time when the program is running, regardless of when it starts and when it ends, its value is solidified in the code, which we call a compile-time constant;
readonly Specifies its value at the first initial time of a particular instance (after the constructor is out, it cannot be changed for this instance) or as a static member at runtime, which we call the run-time constant.
Let's talk about Const first:
1.const because its values never change, we call them constants, constants are always static, so the const is natural static, we can no longer use static modifier const. As shown in the following: the correct definition should be the const float pi=3.14159f; 2.const since it is static, so it belongs to the entire class and not to an instance, we can call it directly through the class name., as shown below:3. Because the value of a constant is directly embedded in the code, you do not need to allocate any memory for the constant at run time, you cannot get the address of the constant, and you cannot pass the constant as a reference.What is direct embed code? That is, in the process of compiling, the compiler first saves the constant value into the assembly metadata, where the constant is referenced, the compiler extracts the constant value and embeds it in the generated IL code, which is why the constant does not need to allocate any memory. Let's verify the above conclusion, first we define a constant:
1 Public class Mathhelper 2 {3 Public Const float 3.14159F ; 4 }
Call:
1 Static void Main (string[] args)2{3 float pi= mathhelper.pi; 4 }
We look at the generated IL code, as follows: The red line, that is, the value of the pi is directly embedded in the code. It is not difficult to understand this, but this writing poses a potential problem: const does not support a cross-version that is well-supported for assemblies. To illustrate this problem, we need to make the following modifications to our code:
The first step:We put Mathhelper in a separate project and generate a separate assembly (Assembly version: 1.0).
Step Two:We compile the application as an EXE file, using the method above to view the IL code, we see that the const value is still embedded in the code.
Step Three:We modify the value of pi to 3.14, recompile mathhelper, and generate a separate assembly (Assembly version: 2.0).
Fourth Step:Since we just recompiled the assembly where Mathhelper is located and did not recompile the EXE, we looked at the IL code of the EXE and found that the value of the embedded code was still 3.14159. That is, in a cross-assembly reference, when a constant is changed, the change cannot be reflected in the reference unless all assemblies that reference the constant are recompiled. Although there is such a bug, it is not to say that Const is useless, because the const in the program does not occupy memory, so it is very fast, so we design the program, if a value never changes, We can define constants to seek an increase in speed efficiency. For example, when our programs need to be internationalized, the code for Simplified Chinese is 2052, and American English is encoded as 1033, and we can define them as constants. In addition, we have said that constants are not addresses and therefore cannot pass constants in the way they are quoted, that is, the following notation is incorrect:
to finish the const, let's say readonly.1.readonly is an instance, so the readonly variable is not directly accessible through the class nameDefined:
1 Public class Mathhelper 2 {3 Public ReadOnly float PI; 4 }
Access:2.readonly out of the constructor, for this instance is immutable, so the following syntax is also wrongSince we emphasize "out of the constructor", does that mean that we can change its value one or more times within the build function? In order to verify our conjecture, our mathhelper is transformed as follows:
1 Public classMathhelper2 {3 PublicMathhelper ()4 {5 This. PI =3.15F;6 This. PI =3.14F;7 }8 Public ReadOnly floatPI;9}
Calling code:
1 Static void Main (string[] args)2{3 new mathhelper (); 4 Console.WriteLine (M.PI); 5 }
Output results: From the above results, we can see that the readonly variable can be assigned multiple times in the constructor, but once the build function is read-only.3. With the support of the 2nd, we can now verify that
ReadOnly is an example of the (immutable first case) conclusion.We retrofit Mathhelper as follows:
1 Public class Mathhelper 2 {3 Public Mathhelper (float pi)4 {5this . PI = pi; 6 }7public readonlyfloat PI; 8 }
The call is as follows:
1 Static voidMain (string[] args)2 {3Mathhelper M1 =NewMathhelper (3.14F);4 Console.WriteLine (M1. PI);5 6Mathhelper m2 =NewMathhelper (3.15F);7 Console.WriteLine (M2. PI);8 9 Console.read ();Ten}
Output: We instantiate two different mathhelper, give pi different values, pi values belong to different instances, this also validates our conclusion.inline notation for 4.readonlyThe children's shoes said, and I used this way of writing, which shows that ReadOnly can be assigned outside of the build method. As shown below:
1 Public class Mathhelper 2 {3 Public ReadOnly float pi=3.15F; 4 }
In fact, this is an inline notation, a syntactic sugar of C #, just a syntactic simplification, which is actually initialized in the constructor. C # allows the use of this simplified inline initialization syntax to initialize the class's constants, Read/write fields, and readonly fields.5.readonly Assignment Second case: What happens if I modify readonly with static?In front of the const, we said that Const is static and this static cannot be explicitly specified, so adding static before const causes compiler compilation to fail. What happens when we readonly static?first, we determine that static is a class, at which point we cannot specify the ReadOnly by constructors.
1 Public class Mathhelper 2 {3 Public Static ReadOnly float pi=3.14F; 4 }
Call:
1 Static void Main (string[] args)2{3 Console.WriteLine (MATHHELPER.PI); 4 console.read (); 5 }
The results are consistent with our expectations: But our doubts don't stop there: Since the static readonly is also a class, and its value cannot be assigned by a constructor, will the compiler write its value to the IL code like a const? We decompile its IL code as follows: As you can see, The value is not embedded in the code. So, we can boldly predict that
This notation does not cause cross-version issues that support assemblies.This does not write the verification process, left to the readers to explore their own friends. Since there is no embed code, when the program runs, its value is when to allocate memory? We cite a sentence from the CLR via C # (4th edition) to illustrate this issue:
for static fields, where dynamic memory is allocated in the class, and the class is created when the type is loaded into the AppDomain, when is the type loaded into the AppDomain? The answer is: This is usually the first time any method that references that type is JIT-compiled. For instance fields in the previous 3rd, the dynamic memory is allocated when an instance of the type is constructed.
Three. What is immutable?
Before we spent a lot of space to explain the const and readonly variables when the beginning of immutable, some from the beginning of the immutable, some of the first time the load is immutable, some of the constructor is not variable, but we have a very critical problem is not clear: what is not mutable? Perhaps the children's shoes are very puzzled, the value is immutable Bai! That's not exactly right. To understand this problem, we need to understand the const and readonly modified objects, that is, our unchanging content.
Const can modify primitive types: Boolean, Char, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, and string. You can also modify class classes, but set the value to null. The struct cannot be decorated because the struct is a value type and cannot be null. For primitive types, values are stored on the stack, so we can assume that the value itself is constant, where string is a special reference type, where it also has a characteristic of a value type, so it can also be assumed that it is the value itself.
for ReadOnly, ReadOnly can modify any type.For primitive types, we can think of it as the same as const, but for reference types we need to be cautious and not take it for granted, and let's conclude by experimenting:
1 Public classAlphabet2 {3 Public Static ReadOnlychar[] Letters =NewChar[] {'A','B','C','D','E','F' };4}
Call:
1 Static voidMain (string[] args)2 {3alphabet.letters[0] ='a';4alphabet.letters[0] ='b';5alphabet.letters[0] ='C';6alphabet.letters[0] ='D';7alphabet.letters[0] ='e';8alphabet.letters[0] ='F';9 Console.WriteLine (Alphabet.Letters.Length);Ten Console.read (); One}
Can be assigned a value!!! The output is as follows: Now, let's give it a new object: NOT assignable!!! Do you have an answer in your heart when you see this?
Conclusion: For reference types, we can assign values instead of assigning a new object, because there is no change to the reference, not to the referenced object.
Four: summary
to this, our const and readonly of the discovering type of parsing also is over, said so much, we actually want to illustrate the following 2 points:
1.const does not change at any time, faster than ReadOnly, but does not solve the cross-version assembly problem, ReadOnly static when the first JIT compiles unchanged, the instance when the constructor is out of the instance is immutable.
The 2.const modifier primitive type, constant is the value, the value of the readonly is not changed when the reference type is modified, and its reference is unchanged.Above.
Reference Documentation:
CLR via C # (4th edition), "Effice C #: 50 Proven ways to improve C # code", "writing high-quality code: 157 Recommendations for improving C # programs" blog: Http://www.cnblogs.com/royenhome/archi Ve/2010/05/22/1741592.html
The const and readonly of C # discovering