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

La palabra clave out hace que los argumentos se pasen por referencia.The out keyword causes arguments to be passed by reference. Hace que el parámetro formal sea un alias para el argumento, que debe ser una variable.It makes the formal parameter an alias for the argument, which must be a variable. En otras palabras, cualquier operación en el parámetro se realiza en el argumento.In other words, any operation on the parameter is made on the argument. Esto es como la palabra clave ref, salvo que ref requiere que se inicialice la variable antes de pasarla.It is like the ref keyword, except that ref requires that the variable be initialized before it is passed. También es como la palabra clave in, salvo que in no permite que el método llamado modifique el valor del argumento.It is also like the in keyword, except that in does not allow the called method to modify the argument value. 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.To use an out parameter, both the method definition and the calling method must explicitly use the out keyword. Por ejemplo:For example:

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.The out keyword can also be used with a generic type parameter to specify that the type parameter is covariant. Para obtener más información sobre el uso de la palabra clave out en este contexto, vea Out (Modificador genérico).For more information on the use of the out keyword in this context, see out (Generic Modifier).

Las variables que se han pasado como argumentos out no tienen que inicializarse antes de pasarse en una llamada al método.Variables passed as out arguments do not have to be initialized before being passed in a method call. En cambio, se necesita el método que se ha llamado para asignar un valor antes de que el método se devuelva.However, the called method is required to assign a value before the method returns.

Las palabras clave in, ref y out no se consideran parte de la firma del método con el fin de resolver la sobrecarga.The in, ref, and out keywords are not considered part of the method signature for the purpose of overload resolution. 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.Therefore, methods cannot be overloaded if the only difference is that one method takes a ref or in argument and the other takes an out argument. Por ejemplo, el código siguiente, no se compilará:The following code, for example, will not compile:

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í:Overloading is legal, however, if one method takes a ref, in, or out argument and the other has none of those modifiers, like this:

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.The compiler chooses the best overload by matching the parameter modifiers at the call site to the parameter modifiers used in the method call.

Las propiedades no son variables y, por tanto, no pueden pasarse como parámetros out.Properties are not variables and therefore cannot be passed as out parameters.

Las palabras clave in, ref y out no pueden usarse para estos tipos de métodos:You can't use the in, ref, and out keywords for the following kinds of methods:

  • Métodos asincrónicos, que se definen mediante el uso del modificador async.Async methods, which you define by using the async modifier.

  • Métodos de iterador, que incluyen una instrucción yield return o yield break.Iterator methods, which include a yield return or yield break statement.

Declaración de parámetros outDeclaring out parameters

Declarar un método con el argumento out es una solución alternativa clásica para devolver varios valores.Declaring a method with out arguments is a classic workaround to return multiple values. A partir de C# 7.0, considere las tuplas para escenarios similares.Beginning with C# 7.0, consider tuples for similar scenarios. En el ejemplo siguiente, se utiliza out para devolver tres variables con una única llamada al método.The following example uses out to return three variables with a single method call. Tenga en cuenta que el tercer argumento se asigna a null.Note that the third argument is assigned to null. Esto permite que los métodos devuelvan valores opcionalmente.This enables methods to return values optionally.

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 outCalling a method with an out argument

En C# 6 y versiones anteriores, debe declarar una variable en una instrucción independiente antes de pasarla como un argumento out.In C# 6 and earlier, you must declare a variable in a separate statement before you pass it as an out argument. 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.The following example declares a variable named number before it is passed to the Int32.TryParse method, which attempts to convert a string to a number.

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

A partir de C# 7.0, puede declarar la variable out en la lista de argumentos de la llamada al método, en lugar de en una declaración de variable independiente.Starting with C# 7.0, you can declare the out variable in the argument list of the method call, rather than in a separate variable declaration. 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.This produces more compact, readable code, and also prevents you from inadvertently assigning a value to the variable before the method call. El ejemplo siguiente es como el ejemplo anterior, excepto que define la variable number en la llamada al método Int32.TryParse.The following example is like the previous example, except that it defines the number variable in the call to the Int32.TryParse method.

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.In the previous example, the number variable is strongly typed as an int. También puede declarar una variable local con tipo implícito como se muestra en el siguiente ejemplo.You can also declare an implicitly typed local variable, as the following example does.

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#C# Language Specification

Para obtener más información, consulte la Especificación del lenguaje C#.For more information, see the C# Language Specification. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.The language specification is the definitive source for C# syntax and usage.

Vea tambiénSee also