out 參數修飾詞 (C# 參考)out parameter modifier (C# Reference)

out 關鍵字會導致引數由參考傳遞。The out keyword causes arguments to be passed by reference. 它會使形式參數成為引數的別名,其必須為變數。It makes the formal parameter an alias for the argument, which must be a variable. 換句話說,參數上的任何作業都會在引數上進行。In other words, any operation on the parameter is made on the argument. 它類似於 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 關鍵字也可以和泛型型別參數一起使用,指定型別參數為 Covariant。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.

針對多載解析的目的,inrefout 關鍵字不被視為方法簽章的一部分。The in, ref, and out keywords are not considered part of the method signature for the purpose of overload resolution. 因此,如果唯一的差別是一種方法採用 refin 引數,而另一種方法採用 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) { }
}

但如果有一種方法採用 refinout 引數,而另一種方法完全沒有這些修飾詞,則類似於: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.

您不可為下列幾種方法使用 inrefout 關鍵字:You can't use the in, ref, and out keywords for the following kinds of methods:

  • 使用 async 修飾詞定義的 async 方法。Async methods, which you define by using the async modifier.

  • 迭代器方法,其包括 yield returnyield break 陳述式。Iterator methods, which include a yield return or yield break statement.

此外, 擴充方法 具有下列限制:In addition, extension methods have the following restrictions:

  • out關鍵字不能用在擴充方法的第一個引數上。The out keyword cannot be used on the first argument of an extension method.
  • ref當引數不是結構,或是不受限於不是結構的泛型型別時,無法在擴充方法的第一個引數上使用關鍵字。The ref keyword cannot be used on the first argument of an extension method when the argument is not a struct, or a generic type not constrained to be a struct.
  • in除非第一個引數是結構,否則無法使用關鍵字。The in keyword cannot be used unless the first argument is a struct. in關鍵字不能用於任何泛型型別,即使當條件約束為結構時也一樣。The in keyword cannot be used on any generic type, even when constrained to be a struct.

宣告 out 參數Declaring out parameters

使用 out 引數來宣告方法是傳回多個值的傳統因應措施。Declaring a method with out arguments is a classic workaround to return multiple values. 從 c # 7.0 開始,請考慮類似案例的 值元組Beginning with C# 7.0, consider value tuples for similar scenarios. 下列範例使用 out,在單一方法呼叫中,傳回三個變數。The following example uses out to return three variables with a single method call. 第三個引數會指派給 null。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);

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

呼叫有 out 引數的方法Calling 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. 下列範例與上一個範例類似,但下列範例會在對 Int32.TryParse 方法的呼叫中定義 number 變數。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