Three advanced parameters ref out and params for C #
In our study of C # Foundation, we will learn the C # three advanced parameters, respectively, is out. Ref and params, here we are to explain separately, here we do not do a specific explanation, I will use a few examples to do the separate interpretation.
One: Out parameter
1. First of all, I'll give you a question: Let's write a method to find the maximum, minimum, sum, and average values in an array. The code is as follows:
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9};
through the analysis we will find that if we write a method, when we need to return a value, we can only return a value, this time we need to find the maximum, minimum, sum and average value. How are we supposed to write it?? If we have not studied out parameters, we can consider returning an array, and assuming the maximum, minimum, sum of the elements in the array, respectively. (when the sum is calculated, the average value comes out). The detailed generations are as follows:
We declare an array of length 4, assuming res[0] maximum res[1] minimum res[2] sum res[3] mean int[] res = new INT[4]; Assume that the first element in the array is the maximum value res[0] = Nums[0];//max //Assuming the second element in the array is the minimum value res[1] = nums[0];//min // Assume that the third element in the array is a sum
Note: num[0]: This is just the value we assume.
2. At this time we need to traverse for loop, if the current loop to the element is larger than my maximum value, the current element is assigned to my maximum value, if the current loop to the element is smaller than my minimum value, the current element is assigned to my minimum value, the sum is all the elements added, the average is the sum/ The length of the array. The detailed code is as follows:
for (int i = 0; i < Nums. Length; i++) { //If the element that is currently being looped is larger than the maximum value I assumed if (Nums[i] > Res[0]) { //assigns the current loop to the element to my maximum res[0] = nums[ I]; } If the current loop to the element is smaller than my minimum if (Nums[i] < res[1]) { //The current element is assigned to my minimum value res[1] = nums[i]; } Sum res[2] + = Nums[i]; }
3. This is the time to return the array directly, the complete code is as follows:
1//<summary> 2///Calculate the maximum, minimum, sum, average of an array of 3//</summary> 4//<param NA Me= "Nums" ></param> 5//<returns></returns> 6 public static int[] Getmaxminsumavg (in T[] nums) 7 {8//We declare an array of length 4, assuming res[0] maximum res[1] min res[2] sum res[3] mean 9 int[] Res = new INT[4];10//assuming the first element in the array is the maximum value of res[0] = nums[0];//max12//Assuming the second element in the array is the minimum value 13 RES[1] = NUMS[0];//MIN14//Assuming that the third element in the array is the sum of res[2] = 0;//SUM16 for (int i = 0; I < Nums. Length; i++) 17 {18//If the element that is currently being looped is larger than the maximum value I assumed (Nums[i] > res[0]) 20 {21//assigns the element that is currently looping to my maximum value res[0] = nums[i];23}24 If the element you are looping to is smaller than my minimum value if (Nums[i] < res[1]) 26 {27//Assign the current element to me The minimum valueRES[1] = nums[i];29}30//sum res[2] + = nums[i];32 }33//Average res[3] = res[2]/nums. length;35 return res;36}
4. Next is called in the Main method, as follows:
5. At this point we need to consider a question, I want to return the value of type bool in the array or return a value of type string, what do we do then?? When the out parameter is needed, the out parameter is focused on returning several different types of values in a method, but it has an important feature: it must be assigned within the method.
(1). Add the Out keyword before the value that we need to return.
(2). When we call our methods in the main method, we first need to declare the variables.
The idea of solving the problem is the same as above. Here is not to do too much explanation, the direct complete code to serve:
<summary>////Calculate the maximum, minimum, average, sum of an array of integers///</summary>//<param name= "Nums" & gt; Required value array </param>//<param name= "Max" > Excess return maximum </param>//<param name= "min" > excess returned Min </param>//<param name= "sum" > Excess return sum </param>//<param name= "avg" > Excess return Average < /param> public static void Test (int[] nums, out int max, out int min, out int sum, out int avg) { The out parameter requires that it be assigned within the method//We assume that the first element in the array is the maximum value max = nums[0]; Suppose the first element in the array is the minimum value min = nums[0]; The sum is set to zero sum = 0; for (int i = 0; i < Nums. Length; i++) {if (Nums[i] > max) {max = nums[i]; } if (Nums[i] < min) {min = nums[i]; } sum + = Nums[i]; } AVG = sum/nums. Length; }
1 static void Main (string[] args) 2 {3 //write a method to find the maximum, minimum, sum, average 4 int[] numbers = {1, 2, 3, 4, 5, 6 in an array , 7, 8, 9}; 5 //variable declaration 6 int max1; 7 int min1; 8 int sum1; 9 int avg1;10 //method call one Test (numbers, out Max1, out Min1, off sum1, out AVG1); Console.WriteLine (max1); Console.WriteLine (min1) ; Console.WriteLine (SUM1), Console.WriteLine (AVG1), Console.readkey ();
The results of the debugs are as follows:
6. Now I do an exercise with out parameters: The user is prompted to enter a user name and password, write a method to determine whether the user entered the correct, return to the user a login results, and also to return to the user a login information, if the user name is wrong, in addition to return the login results, but also return a "User name error", and if the password is incorrect, return a "password error" In addition to returning the login result.
Analysis of the idea: through the above questions we analyze not only to return a login results, but also to return a login information (whether the login error or password error or unknown error), we need to consider the use of out parameters. The complete code is as follows:
Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; namespace _08 use out parameter to login {class Program {static void Main (string[] args) {Console.writelin E ("Please enter user name"); String userName = Console.ReadLine (); Console.WriteLine ("Please enter password"); String userpwd = Console.ReadLine (); String msg; BOOL B = IsLogin (UserName, userpwd, out msg); Console.WriteLine ("Login result {0}", b); Console.WriteLine ("Login information {0}", msg); Console.readkey (); }///<summary>//To determine if the login is successful///</summary>//<param name= "name" > Username </p aram>//<param name= "pwd" > Password </param>//<param name= "MSG" > Extra returned login information </param> <returns> return to login results </returns> public static bool IsLogin (string name, string pwd, out string msg) {if (name = = "Admin" &&Amp PWD = = "888888") {msg = "login Successful"; return true; } else if (name = = "Admin") {msg = "bad password"; return false; } else if (pwd = = "888888") {msg = "user name error"; return false; } else {msg = "Unknown error"; return false; } } }}
The results are as follows:
Second: Then let's talk about the use of the ref parameter.
Well, then, let's take a look at this problem first: Use a method to swap two variables of type int.
Thinking Analysis: First of all, this is a very classic face test, we can use two methods to do this problem (here is not a detailed explanation).
First, declare a method to implement the interchange of two int type variables. The code is as follows:
1// <summary> 2// Exchange two variables of type int 3// </summary> 4// <param name= "N1" > First parameter </param> 5 //<param name= "N2" > second parameter </param> 6 public static void Test (int n1, int n2) 7
{8 n1 = n1-n2;//-10 9 n2 = n1 + n2;//-10 1010 n1 = n2-n1;//20 1011 }
At this point, consider that we can implement the result by invoking it in the Main method?? The answer is no. This is designed to our value types and reference types (explained in detail later). We are going to use our ref parameter at this time. At this point we define a ref parameter: The ref parameter can take a variable into a method and change it, after the change is completed, the value of the change is taken out of the method. Features: The ref parameter requires that a value be assigned to the outside of the method and can be unassigned within the method.
The complete code is as follows:
Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; Namespace _11_ref Exercise { class program { static void Main (string[] args) { //use method to exchange two variables of type int It must be assigned an int n1 = Ten on the outside of the method; int n2 =; Test (ref n1, ref N2); Console.WriteLine (N1); Console.WriteLine (n2); Console.readkey (); } <summary>/// Exchange two variables of type int///</summary>// <param name= "N1" > First parameter </param > //<param name= "N2" > second parameter </param> public static void Test (ref int n1, ref int n2) {
//method can be unassigned n1 = n1-n2;//-10 N2 = n1 + n2;//-10 N1 = n2-n1;//20 }}}
The result of the code is as follows:
Three: Let's introduce the params variable parameter.
This time our topic is: to seek the number of arbitrary length and (integer type).
We give the definition directly: the argument list is treated as an element in the array as an element that is consistent with the variable parameter type. Features: The params variable parameter must be the last element in the formal parameter list.
Look directly at the code:
Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; Namespace _12params variable parameter { class program { static void Main (string[] args) { int sum = getsum (8,9); C5/>console.writeline (sum); Console.readkey (); } <summary> /////// </summary> //<param name= "n" > Array </param> / <returns> return sum </returns> public static int getsum (params int[] n) { int sum = 0; for (int i = 0; i < n.length; i++) { sum + = N[i] ; } return sum;}} }
Did you see that when we were going to do 8 and 9 as an element of our parameter list array, we would have realized our function.
Four: This time we should discuss why the out parameter and the ref parameter can implement such a function. For example, take ref parameters:
Let's talk about the difference between a value type and a reference type before we discuss this issue.
(1): Value types and reference types are not stored in the same place in memory.
(2): When passing value types and passing reference types, they are passed differently, value types we call value passing, reference types we call reference passing.
Value type: int double bool char decimal struct enum
Reference type: String custom class Array Object collection interface
Before giving an example, let me first say two important concepts:
(1): When a value type is copied, the value is passed by itself.
(2): When a reference type is copied, a reference to the object is passed.
First of all, let's start with the first example, the code is as follows:
Value passing and reference passing int n1 = 10;int N2 = n1;n2 = 20; Console.WriteLine (N1); Console.WriteLine (n2); Console.readkey ();
Let's guess what the result is. The answer is: 10 20, because int is a value type, when I declare int n1=10, it's equivalent to opening up a memory address in the memory stack, how do we find our value in our memory (that is, we give the memory area a name, our variable name), OK, When an int n2=n1 is executed, that is, an assignment is performed, as stated above, when the value type is passed, we pass the value itself. So when we execute the second line of code, N2=10, when the third line of code is executed, and re-assigned to the N2 n2=20, the result of all output is: n1=10,n2=20. The drawing is represented as follows:
Next we look at the second example (the person defaults to a custom class):
1 person p1 = new Person (); 2 P1. Name = "Zhang San"; 3 person p2 = p1;4 P2. Name = "John Doe"; 5 Console.WriteLine (P1. Name); 6 Console.readkey ();
this time P1. What is the name?? The answer is: John Doe. First of all we must be the person is a custom class, because our custom class is a reference type, so when the reference is passed the reference to this object (memory address). When we declare the code of the first line, we will open an area in the heap of memory to store the new person (); When assigning a value to its name, Zhang San is also stored in the heap, which also opens a space in the stack to store the address that points to the area. So when the person p2=p1 is executed, a copy of P1 's reference to the stack is copied to P2, so now they are pointing to the same area in the heap. So when the name is re-assigned, the value of the P1 will change. as follows:
The drawing is represented as follows:
A third example: The code is as follows:
1 string s1 = "Zhang San"; 2 string s2 = s1;3 s2 = "John Doe"; 4 Console.WriteLine (S1); 5 Console.WriteLine (S2); 6 console.readkey ();
What are our S1 and S2 at this time?? After my test answer is: S1: Zhang San, s2: John Doe. Why is it? Would it be John Doe to follow our process? Because our strings are very special, it is because of the immutable character of the string that we do not have to re-create an area in the heap to store it every time we assign a value to it. So there is no relationship between the two regions.
Question of thought: this time we look at the example of implementing a swap variable in a method, when we are not using ref, we pass the value itself, and when we use the ref parameter, we pass the reference (memory address) of the object. So we conclude that ref has the function of: the ref parameter can change a value pass to a reference pass.
OK, our C # three high-level parameters are introduced here, if you have any questions, you can leave a message, we progress together.
On the three advanced parameters of C # ref out and params