I. Primitive Types For basic types, the situation seems to be simple. Suppose we have the following sequence: // example 1using system; class mainclass {public static void main () {char c = 'a '; Console.writeline ("1 #: c =" c); prmtvfun (c); console.writeline ("2 #: c =" c);} static void prmatvfun (char c) {C ;}} Compile it and run with CSC, you can find that the output of the console is: 1 #: c = a2 #: c = a This indicates that the method prmatvfun (char c) does not really modify the CHAR variable corresponding to the parameter C. What is this? Reason? In MSDN, we see this description: if a parameter is declared for a Method WITHOUT REF or OUT, The Parameter Can Have a value associated with it. That Value Can Be Changed in The Method, But The Changed Value Will Not Be retained when Control Passs Back to the calling process, if you want to modify, it is quite simple, just need to use the keyword REF or OUT of the C #. About the Ref keyword, you can refer to MSDN (I am using MSDN Library - January 2002): ms-help: //ms.msdnqtr.2002jan.1033/csref/html/vclrfref.htm. Out keyword, you can refer to: ms-help: //ms.msdnqtr.2002jan. 1033 / CSREF / HTML / VCLRFOUT.HTM As seen in the documentation, these two keywords don't have much difference. Their main difference is: If the variable is incorporated into the REF mode, it must be in progress The function is initialized; if the variable is incorporated into the OUT mode, it must be assigned to the function body. Below is an example: // Example 2using system; class mainclass {public static vo ID main () {char c = 'm'; // must initialize first console.writeline ("1 #: c =" c); prmtvfunwithref (REF C) When you call, you must explicitly use the REF keyword Console.writeline ("2 #: c =" c); char d; // Does not necessarily initialize, of course, should also be initialized //conswiteline ("3#: d = " D); prmatvfunwithout // When calling, the OUT keyword console.writeline must be explicitly used ("4 #: D =" D);} static void prmatvfun (CHAR C) {c = 's'; // the change value will not be RETAINED WHEN CONTROL PASSES BACK TO The CALLING Procedure} Static Void PrmtvFunwithref (Ref CHAR C) {// Use the REF keyword, c must be initialized C = 's';} static void prmtvfunwithout (Out char C) {// OUT keyword c = 'n';
/ / Must be assigned to C}} This is its output: 1 #: c = m2 #: c = s4 #: d = n no doubt, this modification is successful. Conclusion: For the basic type (Primitive Types), when the parameter as a function is passed, if the REF or OUT keyword is not used, any modifications to which it will not be used in the function body. If it is used correctly REF or OUT keyword, then for the parameters, its corresponding "this" also feels the same. II. Object Types For the object type, if you think the relative complexity of its structure is passed as a parameter transmission It is more complicated than basic types, then you are wrong. In fact, its delivery is not complex: // Example 3using system; class testclass {// a class for test private char C; public char c { // Simple attribute set {c = value;} get {return c;}} // Constructor PUBLIC TESTCLASS (CHAR C) {this.c = c;}} // ========== == TestClass defines this end =========== Class mainclass {// main class public static void main () {testclass tc = new testclass ('a'); console.writeline ("1 # : " Tc.c); Objfun (TC, 'B'); console.writeline (" 2 #: " tc.c); Objfunwithref (Ref TC, 'c'); console.writeline (" 3 #: " Tc.c); Objfunwithout (Out TC, 'D'); // Simple use of TC here, this is the same regardless of the object effect without new, 4 #:" tc.c) Static void objfun (TestClass TC, Char newc) {tc.c = newc;} static void objfunwithref (Ref testclass tc, char NEWC) {tc.c = newc;} static void objfunwithout (Out testclass tc, char c) {tc = new testclass (c);}} In the above program, first define a TestClass class. This class is quite simple. Only one constructor and a CHAR type C property are provided. In the mainclass class, we define some test functions similar to the basic type to determine the transmission mode of the object type. The entire program output is: 1 #: A2 # : B3 #: C4 #: D From these outputs, it can be seen that when the object type object is passed as a function of the parameter (whether or not using keyword REF / OUT, etc.), any modifications in the function body will be modified to itself. Object. Is this this? The answer is a frustrating no! We tried to rewrite the objfun and objfunwithref as the following form: // Example 4
B '* /} static void objfunwithref (Ref testclass tc, char newc) {tc = new testclass (' a '); // Plus this statement tc.c = newc; / * In our example, its value is' C '* /} then compile, run the program, this time the program's output changes to: 1 #: a2 #: A3 #: C4 #: D is not surprising, you may be surprised to 2 # and 3 # output. If If the answer is YES, the output of 2 # is undoubtedly wrong. So, how is the parameter of the object type object function to pass? This problem can be divided into two parts: 1> Do not use REF / OUT keywords, the passage of the parameters and the basic type are uniform: Pass By Value. In order to accept this view, you have to know the concept of reference (this and the reference in Java is the same. . When we write: TestClass TC = New TestClass ('a'); you may not know, you are already using a reference. On the other hand, you may think you have created a TestClass class object --- TC. However, I regret to tell you, you are wrong. You created a TestClass class object, but it is not TC, but the object of New TestClass ('a') is in a heap (HEAP) .TC is Quoted with this object, or tells to the pointer to that object. Like this: When the parameter is passed, as I said: Pass by value. What is the value here? Is a reference! Toned Objfun (TestClass When char), as the basic type, a reference copy is generated. Naturally, this reference copy is also pointing to the same object pointing to the argument: From here we can see if we are in the function body Modified an attribute (like Example 3), because the object points to the COPY OF TC and TC is the same, the modification will naturally be reflected in the object, which is seen in the output of Example 3. The situation is consistent. If the new keyword is used like Example 4, according to our current understanding, it should be like this: From this figure, we can see that TC is still pointing to the original object (Figure Due to the plus ordering method), since the role of NEW, the Copy Of TC is directed to a new object created on the HEAP (the figure is represented by plus double downline in the figure). Shat way, Middle of the function The operation of the TC's copy will not affect the original object. For our EXAMPLE 4, it is still output 2 #: a.2> using the REF / OUT keyword after calling Objfun. Word modified object type instance does not generate a reference copy, but directly use the original reference (naturally pointing to the original object). In this way, any operation will refraction to the original object, if we will objfunwithRef (Ref testclass, char) rewrite is: Static void objfunwithref (Ref testclass tc, char newc) {tc = new testclass ('x'); //tc.c = newc;} Due to REF's role, the original object will become Garbage will ultimately be recycled by GC. At the same time, TC is associated with another object created on HEAP. Therefore, the following output will be generated: 3 #: X Conclusion: For object type (Object Types), When the parameter of the function is passed, if the REF or OUT keyword is not used, the passed is a reference, and generates a reference to a copy. If the REF or OUT keyword is used correctly, then the original reference will be used directly, for this reference Operation, its corresponding "this respect"