There are two types of data in C #: value data and reference data. Distinguish the two types of data during encoding to avoid some minor encoding errors.
First, let's talk about what types are value types, such as basic types such as int, float, and bool, And the types defined by struct, such as datetime. In addition, strings, arrays, and class-defined types are all reference types. For C #, it is difficult to list all types one by one, which requires analysis and summarization in the coding process. To better illustrate the differences between the two types, use the following table.
|
Value Type |
Reference Type |
| MemoryAllocation location |
Allocated in stack |
Allocated in heap |
| Efficiency |
High efficiency, no need for address translation |
Low Efficiency, requiring address translation |
| Memory reclaim |
Recycle immediately after use |
After use, do not recycle immediately, wait for GC to recycle |
| Assignment operation |
To create a new object with the same value. |
Only references the original object. |
| Function parameters and return values |
Is copying objects |
Is the reference of the original object and does not produce new objects |
| Type Extension |
Not easy to expand |
Easy to expand, convenient and Type Extension |
After the above detailed comparison, we have a clear concept of value type and reference type.
However, whether it is a value type or a reference type, it is easy to make mistakes when it is used as a function parameter or return value.
For the value type, when it is used as a function parameter, you want to be modified in the function, then directlyThe following operations cannot be modified.
Public void increment (INT I) { I ++; } |
To make real changes to the passed parameters in the function, you need to use RThe correct format is as follows.
Public void increment (ref int I) { I ++; } |
That is to say, if you need to modify the value type parameter in the function, you need to use ref or out to identify it.
So what is the reference type?
In fact, this problem is easy to understand. First, the pass method parameter in C # adopts the "value copy" mode by default, that is, directly copy a copy of the value type (valuetype) variable, for the reference type, copy a reference copy pointing to the same object and pass it to the method. Therefore, even if the ref keyword is not used, we can change the internal status of the object to which the reference belongs within the method, however, in some cases, we need to create a new object instance in the method and make the original reference point to this new object. The problem arises. Because there are two references, all we need to do is pass the reference copy to the method, and this copy does not work when it is out of the method scope, the original reference still points to the original object. Therefore, we need to use the ref keyword. Instead of referencing a copy, the method is passed to reference itself. We can change the original reference object instance.
Public class data { Public int I = 10; } Public class class1 { Public static void test1 (Data D) { // Parameter D is only a reference copy, and the original referenced variable d points to the same object at the same time, so you can modify the object state. D. I = 100; } Public static void Test2 (Data D) { // Create a new data object and point the parameter d to it. In this case, the parameter D and the original reference D point to two different data objects respectively. Therefore // When the value of the test method is exceeded, the parameter D and the referenced object will lose the reference and wait for GC to recycle. D = new data (); D. I = 200; } Public static void test3 (ref data D) { // Because the ref keyword is used, the parameter D here is referenced in the same way as the original variable D, and no copy is created. Therefore, a new data // The object is feasible. D = new data (); D. I = 300; } Public static void main (string [] ARGs) { Data d = new data (); Console. writeline (D. I); // 10 Test1 (d ); Console. writeline (D. I); // 100 Test2 (d ); Console. writeline (D. I); // 100 Test3 (ref D ); Console. writeline (D. I); // 300 } } |