Модификатор параметров out (справочник по C#)out parameter modifier (C# Reference)

Ключевое out инициирует передачу аргументов по ссылке.The out keyword causes arguments to be passed by reference. Оно схоже с ключевым словом ref за исключением того, что при использовании ref перед передачей переменную необходимо инициализировать.It is like the ref keyword, except that ref requires that the variable be initialized before it is passed. Оно также похоже на ключевое слово in за исключением того, что in не позволяет вызываемому методу изменять значение аргумента.It is also like the in keyword, except that in does not allow the called method to modify the argument value. Для применения параметра out определение метода и метод вызова должны явно использовать ключевое слово out.To use an out parameter, both the method definition and the calling method must explicitly use the out keyword. Например:For example:

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

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

Примечание

Ключевое слово out также можно использовать с параметром универсального типа для указания на то, что тип параметра является ковариантным.The out keyword can also be used with a generic type parameter to specify that the type parameter is covariant. Дополнительные сведения об использовании ключевого слова out в этом контексте см. в разделе out (универсальный модификатор).For more information on the use of the out keyword in this context, see out (Generic Modifier).

Переменные, передаваемые в качестве аргументов out, не требуется инициализировать перед передачей в вызове метода.Variables passed as out arguments do not have to be initialized before being passed in a method call. Но перед передачей управления из вызванного метода он должен присвоить значение.However, the called method is required to assign a value before the method returns.

Хотя ключевые слова in, ref и out вызывают разное поведение во время выполнения, они не считаются частью сигнатуры метода во время компиляции.Although the in, ref, and out keywords cause different run-time behavior, they are not considered part of the method signature at compile time. Таким образом, методы не могут быть перегружены, если единственное различие состоит в том, что один метод принимает аргумент ref или in, а другой — 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. Следующий код, например, компилироваться не будет.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) { }
}

Перегрузка допустима, если один метод принимает аргумент ref, in или out, а другой не использует ни один из этих модификаторов, как показано ниже.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;
}

Компилятор выбирает наиболее подходящую перегрузку, сравнивая модификаторы параметров в месте вызова с модификаторами параметров в вызове метода.The compiler chooses the best overload by matching the parameter modifiers at the call site to the parameter modifiers used in the method call.

Свойства не являются переменными и поэтому не могут быть переданы как параметры out.Properties are not variables and therefore cannot be passed as out parameters.

Ключевые слова in, ref и out запрещено использовать для следующих типов методов.You can't use the in, ref, and out keywords for the following kinds of methods:

  • Асинхронные методы, которые определяются с помощью модификатора async.Async methods, which you define by using the async modifier.

  • Методы итератора, которые включают оператор yield return или yield break.Iterator methods, which include a yield return or yield break statement.

Объявление аргументов outDeclaring out arguments

Объявление метода с аргументами out полезно в случае, если требуется, чтобы метод возвращал несколько значений.Declaring a method with out arguments is useful when you want a method to return multiple values. В следующем примере используется out для возвращения трех переменных с помощью вызова одного метода.The following example uses out to return three variables with a single method call. Обратите внимание, что третьему аргумент присвоено значение null.Note that the third argument is assigned to null. Это позволяет методам возвращать значения по желанию.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);

Шаблон Try предполагает возврат значения типа bool, указывающего на результат выполнения операции (успешно или неудачно), и значения, полученного в результате операции, в аргументе out.The Try pattern involves returning a bool to indicate whether an operation succeeded or failed, and returning the value produced by the operation in an out argument. Этот шаблон используется несколькими методами анализа, например методом DateTime.TryParse.A number of parsing methods, such as the DateTime.TryParse method, use this pattern.

Вызов метода с аргументом outCalling a method with an out argument

В C# 6 и более ранних версиях необходимо было объявлять переменную в отдельном операторе, прежде чем передавать ее как аргумент out.In C# 6 and earlier, you must declare a variable in a separate statement before you pass it as an out argument. В следующем примере переменная number объявляется перед передачей в метод Int32.TryParse, который пытается преобразовать строку в число.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

Начиная с C# версии 7.0 переменную out можно объявлять в списке аргументов вызова метода, а не отдельно.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. Это делает код более кратким и удобным для восприятия, а также предотвращает непреднамеренное присвоение значения переменной перед вызовом метода.This produces more compact, readable code, and also prevents you from inadvertently assigning a value to the variable before the method call. Следующий пример аналогичен предыдущему за тем исключением, что переменная number объявляется в вызове метода 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

В предыдущем примере переменная number строго типизирована как int.In the previous example, the number variable is strongly typed as an int. Вы также можете объявить неявно типизированную локальную переменную, как в приведенном ниже примере.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

Спецификация языка C#C# Language Specification

Дополнительные сведения см. в спецификации языка C#.For more information, see the C# Language Specification. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.The language specification is the definitive source for C# syntax and usage.

См. такжеSee Also