ref (Referencia de C#)
La palabra clave ref hace que un argumento se pase por referencia, no por valor. El efecto de pasar por referencia es que cualquier cambio del parámetro en el método llamado se refleja en el método de llamada. Por ejemplo, si el autor de la llamada pasa una expresión de variable local o una expresión de acceso de elemento de matriz, y el método llamado reemplaza el objeto al que hace referencia el parámetro ref, entonces la variable local del autor de la llamada o el elemento de matriz hacen ahora referencia al nuevo objeto.
Nota |
---|
No confunda el concepto de pasar por referencia con el concepto de tipos de referencia.Estos dos conceptos no son lo mismo.Un parámetro de método puede ser modificado por ref independientemente de si se trata de un tipo de valor o de un tipo de referencia.No hay ninguna conversión boxing de un tipo de valor cuando se pasa por referencia. |
Para usar un parámetro ref, la definición de método y el método de llamada deben utilizar explícitamente la palabra clave ref, como se muestra en el ejemplo siguiente.
class RefExample
{
static void Method(ref int i)
{
// Rest the mouse pointer over i to verify that it is an int.
// The following statement would cause a compiler error if i
// were boxed as an object.
i = i + 44;
}
static void Main()
{
int val = 1;
Method(ref val);
Console.WriteLine(val);
// Output: 45
}
}
Un argumento que se pasa a un parámetro ref debe inicializarse antes de pasarlo. En esto difiere de los parámetros out, cuyos argumentos no tienen que inicializarse explícitamente antes de pasarlos. Para obtener más información, vea out.
Los miembros de una clase no pueden tener signaturas que se diferencien solo por ref y out. Si la única diferencia entre dos miembros de un tipo es que uno de ellos tiene un parámetro ref y el otro tiene un parámetro out, se produce un error de compilador. El código siguiente, por ejemplo, no se compila.
class CS0663_Example
{
// Compiler error CS0663: "Cannot define overloaded
// methods that differ only on ref and out".
public void SampleMethod(out int i) { }
public void SampleMethod(ref int i) { }
}
Sin embargo, la sobrecarga puede realizarse cuando un método tiene un parámetro ref o out y el otro tiene un parámetro de valor, como se muestra en el ejemplo siguiente.
class RefOverloadExample
{
public void SampleMethod(int i) { }
public void SampleMethod(ref int i) { }
}
En otras situaciones que requieran firma coincidente, como ocultar o reemplazar, ref y out forman parte de la signatura y no coinciden entre sí.
Las propiedades no son variables. Son métodos y no se pueden pasar a parámetros ref.
Para obtener información sobre cómo pasar matrices, vea Pasar matrices mediante Ref y Out (Guía de programación de C#).
Las palabras clave ref y out no pueden usarse para los siguientes tipos de métodos:
Métodos asincrónicos, que se definen mediante el uso del modificador async.
Métodos de iterador, que incluyen una instrucción yield return o yield break.
Ejemplo
Los ejemplos anteriores muestran lo que sucede cuando se pasan tipos de valor por referencia. También se puede utilizar la palabra clave ref para pasar tipos de referencia. Pasar un tipo de referencia por referencia permite que el método llamado pueda reemplazar el objeto en el método de llamada al que hace referencia el parámetro de referencia. La ubicación de almacenamiento del objeto se pasa al método como el valor del parámetro de referencia. Si cambia el valor de la ubicación de almacenamiento del parámetro (para que apunte a un nuevo objeto), también debe cambiar la ubicación de almacenamiento a la que se refiere el autor de la llamada. En el ejemplo siguiente se pasa una instancia de un tipo de referencia como un parámetro ref. Para obtener más información sobre cómo pasar tipos de referencia por valor y por referencia, vea Pasar parámetros Reference-Type (Guía de programación de C#).
class RefExample2
{
static void ChangeByReference(ref Product itemRef)
{
// The following line changes the address that is stored in
// parameter itemRef. Because itemRef is a ref parameter, the
// address that is stored in variable item in Main also is changed.
itemRef = new Product("Stapler", 99999);
// You can change the value of one of the properties of
// itemRef. The change happens to item in Main as well.
itemRef.ItemID = 12345;
}
static void Main()
{
// Declare an instance of Product and display its initial values.
Product item = new Product("Fasteners", 54321);
System.Console.WriteLine("Original values in Main. Name: {0}, ID: {1}\n",
item.ItemName, item.ItemID);
// Send item to ChangeByReference as a ref argument.
ChangeByReference(ref item);
System.Console.WriteLine("Back in Main. Name: {0}, ID: {1}\n",
item.ItemName, item.ItemID);
}
}
class Product
{
public Product(string name, int newID)
{
ItemName = name;
ItemID = newID;
}
public string ItemName { get; set; }
public int ItemID { get; set; }
}
// Output:
//Original values in Main. Name: Fasteners, ID: 54321
//Back in Main. Name: Stapler, ID: 12345
Especificación del lenguaje C#
Para obtener más información, consulte la Especificación del lenguaje C#. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.
Vea también
Referencia
Pasar parámetros (Guía de programación de C#)
Parámetros de métodos (Referencia de C#)