c#-method parameters (value parameters, reference parameters, output parameters, array parameters, optional parameters, named parameter calls, this parameter [extension method])

value parameter

Value parameters are the most commonly used parameters.
The formal parameters at the time of declaration 不带任何修饰符are value parameters (formal parameters). The value parameter corresponds to a local variable whose initialization value comes from the actual parameter (actual parameter) provided when calling the method . Changes to the formal parameters inside the method will not affect the actual parameters outside the method. The implication is形参是方法内的一个局部变量,方法调用时形参拷贝了传入的实参的值,此后,形参和实参再无半分瓜葛。

class Program
{
    
    
	static void Main(string[] args)
	{
    
    
		int y = 100;

		Program.PrintAdd(y); // 输出 101
		Console.WriteLine(y); // 输出100
	}

	static void PrintAdd(int x)
	{
    
    
		x = x + 1;
		Console.WriteLine(x);
	}
}

The value parameter is引用数据类型

When the value parameter is a reference data type , the formal parameter copies the reference of the actual parameter, but in essence the actual parameter and the formal parameter are still two different variables. The difference is:

  1. 基本数据类型What is stored is directly the value of basic data. For example, the int type stores integers.
  2. 引用数据类型What is stored is the address of the referenced object. For example, the variable of a class object stores the address of the object.

One thing that is easy to confuse is that
when an object is passed to a method, after its fields are modified through the object in the method, the corresponding fields of the object outside the method will be modified. This may be considered by some people as not at this time. value parameter. In fact, it is still a value parameter. The formal parameter copies the value of the actual parameter, but this value is an address in the reference data type. After copying, the values ​​stored in the formal parameter and the actual parameter are the same address. At this time, the address can be accessed through the formal parameter inside the method. If 形参.字段the value of a certain field is modified at this time (the field type can be a basic data type or a reference data type), the field of the object stored in the address pointed to by the formal parameter is modified, and the formal parameter itself is not modified, because the formal parameter What is saved is only the address of the referenced object. The only 形参 = 新对象way is to modify the formal parameter itself. 形参 = 新对象It does not result in 实参 == 新对象, therefore, still complying with the definition of value parameters.

class Student
{
    
    
	public string name;
	public int age;
}
class Program
{
    
    
	static void Main(string[] args)
	{
    
    
		Student stu = new Student();
		stu.name = "yy";
		stu.age = 100;

		Program.Test(stu);

		// 到这里stu的字段的值分别是:
		name = "xx"; 
		age = 100;
		// 新旧hash code 是不一样的
		Console.WriteLine("hash code: {0}", stu.GetHashCode());
	}

	static void Test(Student stu)
	{
    
    
		// 通过形参stu访问了一个Student对象的字段name,并修改之,此修改外部能感知
		stu.name = "xx"; 
		stu = new Student(); // 形参新赋值了一个新对象,外部实参依旧是旧的对象
		// 这两次赋值是对新对象的字段的赋值,并不会对
		// 旧对象的字段造成影响
		stu.name = "bb";
		stu.age = 20;
		Console.WriteLine("hash code: {0}", stu.GetHashCode());
	}
}

Reference parameters

Formal parameters declared with refmodifiers are 引用参数. Unlike value parameters, reference parameters do not create a new storage location. In other words, the actual parameters and formal parameters of the reference parameters refer to the same storage location.

class Program
{
    
    
	static void Main(string[] args)
	{
    
    
		double a = 20;
		Add(ref a); // a == 21
		Console.WriteLine(a); // a == 21
	}

	static void Add(ref int a)
	{
    
    
		a = a + 1;
		Console.WriteLine(a);
	}
}

Output parameters

Formal parameters declared with outmodifiers are 输出参数. Similar to reference parameters, output parameters do not create new storage locations. The storage location of the formal parameters of the output parameters is exactly the storage location of the actual parameters, that is, the sum of the output parameters is exactly the same 形参variable 实参.

The design of the output parameter is to get the value from inside the method. The initial value of the output parameter will be overwritten inside the method, so the initial value is meaningless and there is no need to assign an initial value. Output parameters can be understood as additional function return values.

class Program
{
    
    
	static void Main(string[] args)
	{
    
    
		double result;
		// 调用时也显式地写上out,让人一看就知道是输出参数
		bool b = TryAdd("1", "100", out result);
		if (b)
			Console.WriteLine("{0} + {1} = {2}", "1", "100", result);
	}

	// a和b能被解析成double并相加成功的话才返回true
	static bool TryAdd(string a, string b, out double res)
	{
    
    
		try
		{
    
    
			res = double.Parse(a) + double.Parse(b);
			return true;
		} catch {
    
    
			res = 0;
			return false;
		}
	}
}

Reference parameters VS output parameters

Keywords outand keywords refare 等效的, that is, the same metadata and IL code will be generated regardless of which keyword is used.
However, the C# compiler treats the two differently. The difference between these two keywords is 谁负责初始化.

  1. out: The caller does not want to initialize the object before calling the method, the called method cannot read the object's value, and the called method must assign a value to it before returning.
  2. ref: The caller must first initialize the value of the parameter before calling the method. The called method can read the parameter or assign a value to the parameter.

Array parameters

Formal parameters declared with paramsmodifiers are 数组参数.

// 普通的数组参数声明
void Method(int[] arr){
    
    ...}
// 调用时需要先创建一个数组,然后再传入
int[] array = new int[]{
    
    1, 2, 3};
XXX.Method(array);

// 如果加上修饰符params就可以直接在调用方法时顺序输入值

// 声明方法
void Method(params int[] arr){
    
    ...}
// 调用
XXX.Method(1, 2, 3);
// 可以直接输入而无需创建数组

Note: The parameter list of a method can only have 0 or 1 paramsparameters, and paramsthe parameters can only be at the end of the parameter list.

Optional parameters

This is what provides default values ​​for parameters when declaring a method 可选参数. Parameters become because they have default values 可选.

...
// 声明一个参数有默认值的方法
public void Method(string name = "李四", int age = 20){
    
    ...}
...

// 因为Method方法有默认值,所以参数是可选的
// 不传入实参,形参默认使用的是默认值
XXX.Method(); // name = "李四", age = 20

Named parameter call

Calling with named parameters can be regarded as a habit of writing code. Generally speaking, when we call a function, we only fill in the value of the parameter (or the name of the variable). For example, XXX.Method(100, "你好");this is considered an anonymous call. The named call requires that the name of the parameter be written explicitly. For example:

...
// 方法
public void Method(int id, string name){
    
    ...}
...

// 匿名调用
XXX.Method(1, "张三");

// 具名调用
XXX.Method(id:1, name:"张三");
// 具名调用可以忽略参数列表的顺序
XXX.Method(name:"张三", id:1); // 这样写等同于上面

this parameter (extension method)

Extension methods, also known as this parameters, can add methods to a class that cannot modify the source code but needs to add methods.
The method must be public staic modified.
The following example adds the ToInt method to the string class:

class Pragram
{
    
    
    static void Main(string[] args)
    {
    
    
        string a = "100";
        // 因为input参数就是this,会
        // 自动传入a,所以不用显式传入
        // 参数
        int b = a.ToInt();
    }
}

// 声明一个静态类,这是string的扩展类
static class StringExtension
{
    
    
	// 对string扩展了ToInt方法
	// 该方法可以将字符串转成int
	// this修饰的必须是第一个参数
    public static int ToInt(this string input)
    {
    
    
        int res;
        try
        {
    
    
            res = int.Parse(input);
        }
        catch
        {
    
    
            res = -1;
        }
        return res;
    }
}

Guess you like

Origin blog.csdn.net/weixin_45345384/article/details/128477208