In-depth understanding of parameter passing

Source: Internet
Author: User
Think about the following results and analyze the cause: namespace referenceparameter
{
Class myclass
{
Private string msginfo;
Public String msginfo
{
Get {return msginfo ;}
Set {msginfo = value ;}
}

Public myclass (string PARAM)
{
This. msginfo = Param;
}
Public myclass ()
{
// Default constructor
}
}
Class Program
{
Static void main (string [] ARGs)
{
Myclass MC = new myclass ("a new message .");
Console. writeline (MC. msginfo );
Changemsga (MC );
Console. writeline (MC. msginfo );
Changemsgb (MC );
Console. writeline (MC. msginfo );
Console. readkey ();
}
Static void changemsga (myclass MC)
{
MC. msginfo = "message has been changed by changemsga ().";
}
Static void changemsgb (myclass MC)
{
MC = new myclass ();
MC. msginfo = "message has been changed by changemsgb ().";
}
}
}

Answer: A new message.
Message has been changed by changemsga ().
Message has been changed by changemsga ().

From the perspective of such a basic question, the transfer of myclass (reference type) parameters should be of the same nature as the parameter transfer of the value type, and both are value transfer. The following two conclusions can be drawn:

1) Pass the reference type by value
2) Pass the value type by value

This may be a bit strange, because we generally think that the reference type variable is passed as a parameter.

As shown in the preceding example, after the changemsga () method is called, The msginfo value in the original parameter variable is indeed changed. However, if changemsgb () is called () but it does not affect the original variable itself. It does mean that when an object exceeds its scope, it will become invalid and be recycled by GC.

According to the example, the reference type is generally passed by value (a copy of the variable content is passed), but this value is a reference of the original variable to the content in the managed heap. See the chart description:

The figure clearly shows that when changemsga () is called for the first time, the value in the managed heap pointed by MC is changed internally.
The second call to changemsgb (), because it internally constructs a new myclass, the copy will point to the new reference (right ), therefore, operations on its content will not affect external myclass MC.

So how to change the external value?
1) Pass the value type by reference
2) transfer by reference of the reference type

When the ref keyword is used, the passed parameter MC will not be a reference, but a reference (similar to a pointer). It may be very difficult to say this, so we can think that:

When the ref keyword is used: static void changemsgb (ref myclass MC)
{
MC = new myclass ();
MC. msginfo = "message has been changed by changemsgb ().";
}

Here, myclass Mc only refers to an alias of the external MC and does not assign a copy of the variable in the stack. This alias itself is exactly the external MC itself, therefore, after the ref keyword is used, the operation inside the function is equivalent to directly operating external variables.

A complementary small question:

When the ref keyword and the out keyword are used, all references are passed. The ref keyword requires that the parameter be initialized externally, and the out keyword must be reinitialized in the function body, in addition, CLR does not support function overloading Based on ref and out, for example, static void changemsgb (ref myclass MC) // ref keyword.
{
MC = new myclass ();
MC. msginfo = "message has been changed by changemsgb ().";
}

Static void changemsgb (Out myclass MC) // out keyword
{
MC = new myclass ();
MC. msginfo = "message has been changed by changemsgb ().";
}

In fact, the two sections of Code cannot be passed during compilation. Let's take a look at the translated il code to see why: myclass MC = new myclass ();
Changemsgb (ref MC );

Myclass MC = new myclass ();
Changemsgb (Out MC );

The above two parts will be compiled into the following il code: il_0009: Call void dotnetnecessary. Program: changemsgb (class dotnetnecessary. myclass &)

It can be seen that when calling a changemsgb () static method, the parameter will be marked as & (similar to the address transfer in C ), therefore, the reload cannot be performed only through the differences between the ref and out keywords. Because the generated il code is the same, JIT compilation will not be able to identify which version of the reload is called.

Plus: you must know about anytao recently. net, I tried to learn the essential differences through Il, and then expressed in the form of language and image according to my own understanding, although the topic is basic, if we have a deeper understanding, we will be more impressed and understand it more thoroughly :)

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.