Parámetros del método C# (parámetros de valor, parámetros de referencia, parámetros de salida, parámetros de matriz, parámetros opcionales, llamadas a parámetros con nombre, este parámetro [método de extensión])

parámetro de valor

Los parámetros de valor son los parámetros más utilizados.
Los parámetros formales en el momento de la declaración 不带任何修饰符son parámetros de valor (parámetros formales). El parámetro de valor corresponde a una variable local cuyo valor de inicialización proviene del parámetro real (parámetro real) proporcionado al llamar al método . Los cambios en los parámetros formales dentro del método no afectarán los parámetros reales fuera del método.形参是方法内的一个局部变量,方法调用时形参拷贝了传入的实参的值,此后,形参和实参再无半分瓜葛。

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);
	}
}

El parámetro de valor es引用数据类型

Cuando el parámetro de valor es un tipo de datos de referencia , el parámetro formal copia la referencia del parámetro real, pero en esencia el parámetro real y el parámetro formal siguen siendo dos variables diferentes. La diferencia es:

  1. 基本数据类型Lo que se almacena es directamente el valor de los datos básicos, por ejemplo, el tipo int almacena números enteros.
  2. 引用数据类型Lo que se almacena es la dirección del objeto referenciado, por ejemplo, la variable de un objeto de clase almacena la dirección del objeto.

Una cosa que es fácil de confundir es que
cuando un objeto se pasa a un método, después de que sus campos se modifican a través del objeto en el método, los campos correspondientes del objeto fuera del método se modificarán, lo que algunas personas pueden considerar. como no en este momento parámetro de valor. De hecho, sigue siendo un parámetro de valor. El parámetro formal copia el valor del parámetro real, pero este valor es una dirección en el tipo de datos de referencia. Después de copiar, los valores almacenados en el parámetro formal y el parámetro real son la misma dirección. En este momento, se puede acceder a la dirección a través del parámetro formal dentro del método. Si 形参.字段el valor de un determinado campo se modifica en este momento (el tipo de campo puede ser un tipo de datos básico o un tipo de datos de referencia), se modifica el campo del objeto almacenado en la dirección señalada por el parámetro formal y el valor formal El parámetro en sí no se modifica, porque el parámetro formal Lo que se guarda es solo la dirección del objeto referenciado. La única 形参 = 新对象forma es modificar el propio parámetro formal. Por lo tanto, 形参 = 新对象no resulta en seguir cumpliendo con la definición de parámetros de valor.实参 == 新对象

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());
	}
}

Parámetros de referencia

Los parámetros formales declarados con refmodificadores son 引用参数. A diferencia de los parámetros de valor, los parámetros de referencia no crean una nueva ubicación de almacenamiento. En otras palabras, los parámetros reales y los parámetros formales de los parámetros de referencia se refieren al mismo lugar de almacenamiento.

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);
	}
}

Parámetros de salida

Los parámetros formales declarados con outmodificadores son 输出参数. Al igual que los parámetros de referencia, los parámetros de salida no crean nuevas ubicaciones de almacenamiento. La ubicación de almacenamiento de los parámetros formales de los parámetros de salida es exactamente la ubicación de almacenamiento de los parámetros reales, es decir, la suma de los parámetros de salida es exactamente la misma 形参variable 实参.

El diseño del parámetro de salida es obtener el valor desde dentro del método. El valor inicial del parámetro de salida se sobrescribirá dentro del método, por lo que el valor inicial no tiene sentido y no es necesario asignar un valor inicial. Los parámetros de salida pueden entenderse como valores de retorno de funciones adicionales.

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;
		}
	}
}

Parámetros de referencia VS parámetros de salida

Las palabras clave outy las palabras clave refson 等效的, es decir, se generarán los mismos metadatos y código IL independientemente de la palabra clave que se utilice.
Sin embargo, el compilador de C# los trata de manera diferente. La diferencia entre estas dos palabras clave es 谁负责初始化.

  1. out: La persona que llama no quiere inicializar el objeto antes de llamar al método, el método llamado no puede leer el valor del objeto y el método llamado debe asignarle un valor antes de regresar.
  2. ref: La persona que llama primero debe inicializar el valor del parámetro antes de llamar al método. El método llamado puede leer el parámetro o asignar un valor al parámetro.

Parámetros de matriz

Los parámetros formales declarados con paramsmodificadores son 数组参数.

// 普通的数组参数声明
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);
// 可以直接输入而无需创建数组

Nota: La lista de parámetros de un método solo puede tener 0 o 1 paramsparámetro, y paramslos parámetros solo pueden estar al final de la lista de parámetros.

Parámetros opcionales

Esto es lo que proporciona valores predeterminados para los parámetros al declarar un método 可选参数. Los parámetros se vuelven porque tienen valores predeterminados 可选.

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

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

Llamada de parámetro con nombre

Llamar con parámetros con nombre puede considerarse como un hábito de escribir código. En términos generales, cuando llamamos a una función, solo completamos el valor del parámetro (o el nombre de la variable), por ejemplo, esto se considera una llamada anónima XXX.Method(100, "你好");. . La llamada con nombre requiere que el nombre del parámetro se escriba explícitamente. Por ejemplo:

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

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

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

este parámetro (método de extensión)

Los métodos de extensión, también conocidos como parámetros, pueden agregar métodos a una clase que no puede modificar el código fuente pero necesita agregar métodos.
El método debe ser modificado estáticamente públicamente.
El siguiente ejemplo agrega el método ToInt a la clase de cadena:

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;
    }
}

Supongo que te gusta

Origin blog.csdn.net/weixin_45345384/article/details/128477208
Recomendado
Clasificación