C # function parameter transfer (by value and reference)

Source: Internet
Author: User

Let's talk about the data type in C #. The value type and reference type.
 

Value Type: directly store data values and store them in the memory stack.

Reference Type: stores the reference of the Peer value, which actually stores a memory address. the storage of the reference type is divided into two parts, and the actual value is saved in the managed heap. the actual memory address is saved in the stack.

When the reference type is used, locate the address in the stack and then find the actual value in the heap.

That is to say, stack and heap are used to save the reference type. However, when using the reference type, we only use the value in the stack, and then indirectly access the value in the heap.

C # pre-defined simple types, such as int, float, bool, and char are all value types. In addition, enum (enumeration) and struct (structure) are also value types.

String, array, and custom class are all reference types. The string is a special reference type. C # adds a constant character to it.


C # If ref is not added to a function parameter, a modifier such as out explicitly declares that the parameter is passed by reference, and all values are passed by default.

The following two concepts should be noted: whether the parameter type is a value type or a reference type or whether to pass a value or a reference when passing a parameter.

Assume there are void FunTest (int [] array) and void FunTest (int a) functions. the array parameter is of the reference type and a is of the value type. however, they are passed by value.

 

Let's give an example to illustrate

 

PASS Parameters by value:
Class Program

{

Public static void ChangeInt (int num)

{

Num = 123;

}

Public static void ChangeArray (int [] array)

{

Array [0] = 10;

Array = new int [] {6, 7, 8, 9 };

}

Static void Main (string [] args)

{

Int anum = 1;

Int [] aarray = {1, 2, 3 };


ChangeInt (anum );

ChangeArray (aarray );


Console. WriteLine ("value of num:" + anum );

Console. Write ("value of aarray :");

Foreach (int I in aarray)

Console. Write (I + "");

}

}

Result: value of anum: 1

Value of aarray: 10 2 3

The result may be a bit strange. we generally think that the value transfer is to copy the value, and no matter what changes are made to the input parameter in the function, the value before the parameter will not be affected, so the anum is not changed to 123, still 1

But why does aarray [0] become 10?

We have mentioned that the reference type is saved as two parts in memory, one is the memory address in the stack, and the other is the actual value in the heap. when using this function, we only use the value in the stack. If the value in the stack is 0 xabcdefgh, it means that the value of the stack AAY points to it. when we pass the value, we copy the stack value into another one. Let's say array points to it. it is the same as copying anum value 1.

However, when we operate a value such as the memory address, we will not directly operate on it like an integer, but will only find the actual value in heap through it.

So we use array [0] = 10. it actually changes the value of the array in heap. however, array = new int [] {6, 7, 8, 9} does not affect the aarray before it. this operation is to re-open a memory in heap and save the values 6, 7, 8, 9. this memory address is assigned to array, so its previous value 0xabcdefgh is rewritten. however, the stack value of aarray is still 0 xabcdefgh.


PASS Parameters by reference
 

You can use out or ref to explicitly specify them. They can be used in most cases, but there is only a small difference.

Let's use ref for example. We also use the above example. We just added the keyword ref.

Class Program

{

Public static void ChangeInt (ref int num)

{

Num = 123;

}

Public static void ChangeArray (ref int [] array)

{

Array [0] = 10;

Array = new int [] {6, 7, 8, 9 };

}

Static void Main (string [] args)

{

Int anum = 1;

Int [] aarray = {1, 2, 3 };


ChangeInt (ref anum );

ChangeArray (ref aarray );


Console. WriteLine ("value of num:" + anum );

Console. Write ("value of aarray :");

Foreach (int I in aarray)

Console. Write (I + "");

}

}

Result: value of anum: 123

Value of aarray: 6 7 8 9

It's totally different from the result passed by value.

Num = 123 is easy to understand. Let's talk about why the value of aarray has changed.

When passed by reference, the value in the stack pointed to by aarray will not be copied, but will be passed directly. in this way, when array [0] = 10, the value of 1 2 3 in heap is also changed to 10 2 3. If

Without the statement array = new int [] {6, 7, 8, 9}, the result is exactly the same as that passed by value. however, there is a difference after this sentence. We know the meaning of this sentence and open up a new memory in heap.

The value is 6 7 8 9, and the stack value pointed to by aarray is changed to the memory address that saves 6 7 8 9. the memory containing 10 2 3 still exists, but no one has referenced it. then the Garbage Collector will recycle it.


Supplement:

Let's talk about the small difference between out and ref.

Parameters passed in by ref must be assigned a value first.

As in the preceding example

Int num;

ChangeInt (ref int num );

An error occurs. You must first give num a value of 1.

In addition, the parameters passed in by the out statement can be assigned no value first.

Out num;

ChangeInt (out int num); yes

Another difference is that if the ChangeInt function is used to assign a value to num somewhere, the ref function does not necessarily need to assign a value to num.

In fact, this is intended to be well understood. C # To ensure that num must have a value under any circumstances, it cannot be blank.

Because ref must be used to ensure that the parameter has a value before calling the function, it is not required to assign a value in the function.

The out function does not need to ensure that the parameter must have a value before calling the function, so it must be provided with a value in the function.


Although ChangeInt (ref int num) and ChangeInt (out int num) are different, they coexist and cannot be considered as two different functions.

The ChangeInt (int num) and the above two functions are completely different. They can be put together to coexist.

In this case, the ref and out keywords cannot be saved and must be matched.

 

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.