Today I read 《When is the readonly field not readonly? As you can imagine !!!",It really made me look at it.The S3 method in this article does not need to be mentioned. The key is the structure of S. (I hate such a name !!)
For ease of instruction, I re-wrote a similarCode:
Class program {static void main (string [] ARGs) {fuck F = new fuck (100); F. change (1000, out f); console. read () ;}} struct fuck {public readonly int num; Public fuck (INT value) {num = value;} public void change (INT value, out fuck data) {system. console. writeline (this. num); Data = new fuck (value); system. console. writeline (this. num );}}
The running result is naturally:
100
1000
Why? I changed the definition of fuck to class, that is
Fuck {public readonly int num; Public fuck (INT value) {num = value;} public void change (INT value, out fuck data) {system. console. writeline (this. num); Data = new fuck (value); system. console. writeline (this. num );}}
The running result is:
100
100
The problem must be the processing mechanism of value type and reference type. Although in C #, all types exist in the form of objects, the processing mechanism of value types and reference types is still different.
Let's go back to the readonly issue.
ReadonlyKeyword and Different keywords.ConstFields can only be initialized in the declaration of this field.ReadonlyFields can be initialized in the Declaration or constructor.. Therefore, according to the constructors used,ReadonlyFields may have different values. In addition,ConstThe field isCompile timeConstant, andReadonlyFields can be usedRuntimeConstant
From msdn
According to this section, the readonly field can be changed at runtime. Therefore, readonly can certainly change in functions except constructors.
Let's take a look at how the readonly field is changed.
After entering the change function, we can find that the address of variable F has not changed. At the same time, the address indicated by this keyword is the same as the input parameter data.
After data = new fuck (value) is executed, the address pointed to by this keyword remains unchanged, but the value of this address changes.
In this case, the problem lies in the sentence DATA = new fuck (value. Some friends may be confused about the out keyword, but it does not have much to do with the out keyword.
Here we return to the processing of the Value Type in C.
A value-type variable directly contains values. When a value type variable is assigned to another value type variable, the included values are copied.
From msdn
That is to say, when assigning values to data, C # copies the value of new fuck (value) to the address pointed to by data. This is why this phenomenon does not exist after the fuck statement is changed to a class.
Unlike the value assignment of a reference type variable, the value assignment of a reference type variable only copies the reference to the object, instead of copying the object itself.
From msdn
In this case. Changing the value of readonly does not require such a complicated process.
Gently modify the code:
Unsafe static void main (string [] ARGs) {fuck F = new fuck (100); Fuck * pF = & F; int * P = (int *) PF; * P = 123456; F. change (1000, out f); console. read ();}
The running result is:
123456
1000
However, it is true that such a strange encoding method may cause some strange phenomena. I don't know if this is a. net bug.