1-value transfer and reference Transfer
Passing a value is a copy of the passed value, and passing a reference is the object itself.
Test code:
ClassProgram
{
Staticvoid Main (string [] args)
{
SomeValueType valueParam;
SomeRefType refParam = new SomeRefType ();
// ***** <1> ****
ValueParam. Name = "before excute ";
Console. WriteLine ("value type as a parameter, before execution: {0}", valueParam. Name );
Test. DoSomething (valueParam );
Console. WriteLine ("value type as a parameter, after execution: {0}", valueParam. Name );
Console. WriteLine ("");
// ***** <2> ****
RefParam. Name = "before excute ";
Console. WriteLine ("reference type as parameter, before execution: {0}", refParam. Name );
Test. DoSomething (refParam );
Console. WriteLine ("reference type as parameter, after execution: {0}", refParam. Name );
Console. WriteLine ("");
// ***** <3> ****
ValueParam. Name = "before excute ";
Console. WriteLine ("value type as a parameter, before execution: {0}", valueParam. Name );
Test. DoOtherSomething (valueParam );
Console. WriteLine ("value type as a parameter, after execution: {0}", valueParam. Name );
Console. WriteLine ("");
// ***** <4> ****
RefParam. Name = "before excute ";
Console. WriteLine ("reference type as parameter, before execution: {0}", refParam. Name );
Test. DoOtherSomething (refParam );
Console. WriteLine ("reference type as parameter, after execution: {0}", refParam. Name );
Console. WriteLine ("");
// ***** <5> ****
ValueParam. Name = "before excute ";
Console. WriteLine ("value type reference transfer, before execution: {0}", valueParam. Name );
Test. DoSomething (ref valueParam );
Console. WriteLine ("value type reference transfer, after execution: {0}", valueParam. Name );
Console. WriteLine ("");
// ***** <6> ****
RefParam. Name = "before excute ";
Console. WriteLine ("reference type transfer, before execution: {0}", refParam. Name );
Test. DoSomething (ref refParam );
Console. WriteLine ("reference type transfer, after execution: {0}", refParam. Name );
Console. WriteLine ("");
// ***** <7> ****
ValueParam. Name = "before excute ";
Console. WriteLine ("value type reference transfer, before execution: {0}", valueParam. Name );
Test. DoOtherSomething (ref valueParam );
Console. WriteLine ("value type reference transfer, after execution: {0}", valueParam. Name );
Console. WriteLine ("");
// ***** <8> ****
RefParam. Name = "before excute ";
Console. WriteLine ("reference type transfer, before execution: {0}", refParam. Name );
Test. DoOtherSomething (ref refParam );
Console. WriteLine ("reference type transfer, after execution: {0}", refParam. Name );
Console. WriteLine ("");
Console. ReadKey ();
}
}
ClassSomeRefType
{
Publicstring Name;
}
StructSomeValueType
{
Publicstring Name;
}
ClassTest
{
Publicstaticvoid DoSomething (SomeValueType v)
{
V. Name = "value type param ";
Console. WriteLine ("value type as parameter, in progress:" + v. Name );
}
Publicstaticvoid DoSomething (SomeRefType r)
{
R. Name = "ref type param ";
Console. WriteLine ("reference type as parameter, in progress:" + r. Name );
}
Publicstaticvoid DoOtherSomething (SomeValueType v)
{
V = new SomeValueType ();
V. Name = "change value type param ";
Console. WriteLine ("reference type as parameter, in progress:" + v. Name );
}
Publicstaticvoid DoOtherSomething (SomeRefType r)
{
R = new SomeRefType ();
R. Name = "change ref type param ";
Console. WriteLine ("reference type as a parameter, create an object in the function, execute:" + r. Name );
}
Publicstaticvoid DoSomething (refSomeValueType v)
{
V. Name = "value type param with ref ";
Console. WriteLine ("reference transfer value type, in progress:" + v. Name );
}
Publicstaticvoid DoSomething (refSomeRefType r)
{
R. Name = "ref type param with ref ";
Console. WriteLine ("reference transfer reference type, in progress:" + r. Name );
}
Publicstaticvoid DoOtherSomething (refSomeValueType v)
{
V = new SomeValueType ();
V. Name = "create value type param with ref ";
Console. WriteLine ("reference transfer value type, built-in function object, in execution:" + v. Name );
}
Publicstaticvoid DoOtherSomething (refSomeRefType r)
{
R = new SomeRefType ();
R. Name = "create ref type param with ref ";
Console. WriteLine ("reference transfer reference type, create an object in the function, execute:" + r. Name );
}
}
2. Code Analysis
2.1 value parameter <1>
According to the running results, the value type parameter does not change before and after being passed into the function, that is, the modification of the form parameter does not affect the real parameter.
From the memory allocation perspective, the value type parameters are allocated to the thread stack, and the form parameters are completely copied to the real parameters. Both real parameters and form parameters have their own address space, and there is no association between them.
2.2 reference parameters <2> <4>
According to the running results, parameters of the reference type change before and after being passed into the function. That is to say, the modification of the form parameter directly affects the value of the real parameter.
From the perspective of memory allocation, the parameter of the reference type is allocated to the hosting stack, while the reference of this object is kept on the thread stack. Because the real parameter stores the address of the object in the managed heap, the address that is passed to the form parameter is also the address, so that the form parameter and the real parameter both save the same address reference, they also point to the same object address. If the vp does not create an object in the function, the modifications to the form parameters are directly reflected in the real parameters.
If a new object is created in the rp parameter of the function, the memory allocation is as follows:
It can be seen that the rp points to another created object, and the shape parameter and the real parameter are not associated. Modifying the shape parameter again does not affect the real parameter.
2.3 value type reference Transfer
According to the running results, the value type parameter changes before and after being passed into the function. That is to say, the modification to the form parameter directly affects the value of the real parameter.
From the memory allocation perspective, the address of the real parameter on the thread stack is passed to the form parameter. The form parameter actually points to the position of the real parameter, and the two are completely synchronized.
2.4 transfer a reference type <6> <8>
According to the running results, parameters of the reference type change before and after being passed into the function. That is to say, the modification of the form parameter directly affects the value of the real parameter.
From the perspective of memory allocation, there are some similarities in the form of value-type references passed on the stack. The form parameter stores the real parameter address, and the form parameter does not point to the address of the object on the managed stack, it points to the real parameter, and the real parameter has a reference pointing to the object memory.
If a new object is created in the rp parameter of the function, the memory allocation is as follows:
Compared with <2> <4>, after ref is added, both the real parameter and the form parameter have the same reference from start to end.
Summary: 1) value transfer is a copy of the value of the target object (whether it is a value type or a reference type object, the copy of the reference type value is the address of the Copied object in the managed heap ).
2) The reference transfer is the passed target object, which is the true reference transfer (relative to the reference type transfer ).
The final running result is shown as follows: