Modificador de parâmetro out (Referência de C#)out parameter modifier (C# Reference)

A palavra-chave out faz com que os argumentos sejam passados por referência.The out keyword causes arguments to be passed by reference. Ela torna o parâmetro formal um alias para o argumento, que deve ser uma variável.It makes the formal parameter an alias for the argument, which must be a variable. Em outras palavras, qualquer operação no parâmetro é feita no argumento.In other words, any operation on the parameter is made on the argument. É como a palavra-chave ref, exceto pelo fato de que ref requer que a variável seja inicializada antes de ser passada.It is like the ref keyword, except that ref requires that the variable be initialized before it is passed. Também é como a palavra-chave in, exceto que in não permite que o método chamado modifique o valor do argumento.It is also like the in keyword, except that in does not allow the called method to modify the argument value. Para usar um parâmetro out, a definição do método e o método de chamada devem usar explicitamente a palavra-chave out.To use an out parameter, both the method definition and the calling method must explicitly use the out keyword. Por exemplo:For example:

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

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

Observação

A palavra-chave out também pode ser usada com um parâmetro de tipo genérico para especificar que o parâmetro de tipo é covariante.The out keyword can also be used with a generic type parameter to specify that the type parameter is covariant. Para obter mais informações sobre o uso da palavra-chave out nesse contexto, consulte out (modificador genérico).For more information on the use of the out keyword in this context, see out (Generic Modifier).

Variáveis passadas como argumentos out não precisam ser inicializadas antes de serem passadas em uma chamada de método.Variables passed as out arguments do not have to be initialized before being passed in a method call. No entanto, o método chamado é necessário para atribuir um valor antes que o método seja retornado.However, the called method is required to assign a value before the method returns.

As palavras-chave in, ref e out não são consideradas parte da assinatura do método para fins de resolução de sobrecarga.The in, ref, and out keywords are not considered part of the method signature for the purpose of overload resolution. Portanto, os métodos não poderão ser sobrecarregados se a única diferença for que um método usa um argumento ref ou in e o outro usa um 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 exemplo, o código a seguir, não será compilado: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) { }
}

A sobrecarga será válida, no entanto, se um método usar um argumento ref, in ou out e o outro não tiver nenhum desses modificadores, desta forma: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;
}

O compilador escolherá a melhor sobrecarga correspondendo os modificadores de parâmetro no site de chamada aos modificadores de parâmetro usados na chamada do 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.

Propriedades não são variáveis e portanto não podem ser passadas como parâmetros out.Properties are not variables and therefore cannot be passed as out parameters.

Não é possível usar as palavras-chave in, ref e out para os seguintes tipos de métodos:You can't use the in, ref, and out keywords for the following kinds of methods:

  • Métodos assíncronos, que você define usando o modificador async.Async methods, which you define by using the async modifier.

  • Métodos de iterador, que incluem uma instrução yield return ou yield break.Iterator methods, which include a yield return or yield break statement.

Declarando parâmetros outDeclaring out parameters

Declarar um método com argumentos out é uma solução clássica para retornar vários valores.Declaring a method with out arguments is a classic workaround to return multiple values. Começando com o C# 7.0, considere tuplas para cenários semelhantes.Beginning with C# 7.0, consider tuples for similar scenarios. O exemplo a seguir usa out para retornar três variáveis com uma única chamada de método.The following example uses out to return three variables with a single method call. Observe que o terceiro argumento é atribuído a null.Note that the third argument is assigned to null. Isso permite que os métodos retornem 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

Chamando um método com um argumento outCalling a method with an out argument

No C# 6 e em versões anteriores, você precisa declarar uma variável em uma instrução separada antes de passá-lo como um argumento out.In C# 6 and earlier, you must declare a variable in a separate statement before you pass it as an out argument. O exemplo a seguir declara uma variável chamada number antes de passá-la para o método Int32.TryParse, que tenta converter uma cadeia de caracteres em um 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

Começando com o C#7.0, você pode declarar a variável out na lista de argumentos da chamada de método em vez de declará-la em uma declaração de variável separada.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. Isso produz um código mais compacto e legível, além de impedir que você atribua acidentalmente um valor à variável antes da chamada de método.This produces more compact, readable code, and also prevents you from inadvertently assigning a value to the variable before the method call. O exemplo a seguir é semelhante ao exemplo anterior, exceto por definir a variável number na chamada para o 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

No exemplo anterior, a variável number é fortemente tipada como um int.In the previous example, the number variable is strongly typed as an int. Você também pode declarar uma variável local de tipo implícito, como no exemplo a seguir.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

Especificação da Linguagem C#C# Language Specification

Para obter mais informações, consulte a Especificação da linguagem C#.For more information, see the C# Language Specification. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso de C#.The language specification is the definitive source for C# syntax and usage.

Consulte tambémSee also