Modificador del parámetro out (Referencia de C#)

La palabra clave out hace que los argumentos se pasen por referencia. Hace que el parámetro formal sea un alias para el argumento, que debe ser una variable. En otras palabras, cualquier operación en el parámetro se realiza en el argumento. Esto es como la palabra clave ref, salvo que ref requiere que se inicialice la variable antes de pasarla. También es como la palabra clave in, salvo que in no permite que el método llamado modifique el valor del argumento. Para usar un parámetro out, tanto la definición de método como el método de llamada deben utilizar explícitamente la palabra clave out. Por ejemplo:

int initializeInMethod;
OutArgExample(out initializeInMethod);
Console.WriteLine(initializeInMethod);     // value is now 44

void OutArgExample(out int number)
{
    number = 44;
}

Nota

La palabra clave out también puede usarse con un parámetro de tipo genérico para especificar que el parámetro de tipo es covariante. Para obtener más información sobre el uso de la palabra clave out en este contexto, vea Out (Modificador genérico).

Las variables que se han pasado como argumentos out no tienen que inicializarse antes de pasarse en una llamada al método. En cambio, se necesita el método que se ha llamado para asignar un valor antes de que el método se devuelva.

Las palabras clave in, ref y out no se consideran parte de la firma del método con el fin de resolver la sobrecarga. Por lo tanto, los métodos no pueden sobrecargarse si la única diferencia es que un método toma un argumento ref o in y el otro toma un argumento out. Por ejemplo, el código siguiente, no se compilará:

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

En cambio, la sobrecarga es legal si un método toma un argumento ref, in o out y el otro no tiene ninguno de estos modificadores, como se muestra aquí:

class OutOverloadExample
{
    public void SampleMethod(int i) { }
    public void SampleMethod(out int i) => i = 5;
}

El compilador elige la mejor sobrecarga haciendo coincidir los modificadores de parámetro del sitio de llamada con los usados en la llamada de método.

Las propiedades no son variables y, por tanto, no pueden pasarse como parámetros out.

Las palabras clave in, ref y out no pueden usarse para estos 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.

Además, los métodos de extensión tienen las restricciones siguientes:

  • No se puede usar la palabra clave out en el primer argumento de un método de extensión.
  • No se puede usar la palabra clave ref en el primer argumento de un método de extensión cuando el argumento no es un struct ni un tipo genérico no restringido a ser un struct.
  • No se puede usar la palabra clave in a menos que el primer argumento sea un struct. No se puede usar la palabra clave in en ningún tipo genérico, incluso cuando está restringido a ser un struct.

Declaración de parámetros out

Declarar un método con el argumento out es una solución alternativa clásica para devolver varios valores. Considere la posibilidad de usar tuplas de valores en escenarios similares. En el ejemplo siguiente, se utiliza out para devolver tres variables con una única llamada al método. El tercer argumento se asigna a NULL. Esto permite que los métodos devuelvan valores opcionalmente.

void Method(out int answer, out string message, out string stillNull)
{
    answer = 44;
    message = "I've been returned";
    stillNull = null;
}

int argNumber;
string argMessage, argDefault;
Method(out argNumber, out argMessage, out argDefault);
Console.WriteLine(argNumber);
Console.WriteLine(argMessage);
Console.WriteLine(argDefault == null);

// The example displays the following output:
//      44
//      I've been returned
//      True

Llamar a un método con un argumento out

Puede declarar una variable en una instrucción independiente antes de pasarla como un argumento out. En el ejemplo siguiente se declara una variable denominada number antes de que se pase al método Int32.TryParse, que intenta convertir una cadena en un número.

string numberAsString = "1640";

int number;
if (Int32.TryParse(numberAsString, out number))
    Console.WriteLine($"Converted '{numberAsString}' to {number}");
else
    Console.WriteLine($"Unable to convert '{numberAsString}'");
// The example displays the following output:
//       Converted '1640' to 1640

También puede declarar la variable out en la lista de argumentos de la llamada de método, en lugar de en una declaración de variable independiente. Esto genera un código legible más compacto y, además, evita que asigne un valor a la variable antes de la llamada al método de manera involuntaria. El ejemplo siguiente es como el ejemplo anterior, excepto que define la variable number en la llamada al método Int32.TryParse.

string numberAsString = "1640";

if (Int32.TryParse(numberAsString, out int number))
    Console.WriteLine($"Converted '{numberAsString}' to {number}");
else
    Console.WriteLine($"Unable to convert '{numberAsString}'");
// The example displays the following output:
//       Converted '1640' to 1640

En el ejemplo anterior, la variable number está fuertemente tipada como int. También puede declarar una variable local con tipo implícito como se muestra en el siguiente ejemplo.

string numberAsString = "1640";

if (Int32.TryParse(numberAsString, out var number))
    Console.WriteLine($"Converted '{numberAsString}' to {number}");
else
    Console.WriteLine($"Unable to convert '{numberAsString}'");
// The example displays the following output:
//       Converted '1640' to 1640

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