out var 宣告

C#中的一個常見模式是使用 bool TryParse(object input, out object value) 來安全地解析物件。

out var 宣告是一個提高可讀性的簡單功能。它允許變數在作為 out 引數傳遞的同時宣告。

以這種方式宣告的變數的範圍限定在宣告它的位置的主體的其餘部分。

在 C#7.0 之前使用 TryParse,你必須宣告一個變數以在呼叫函式之前接收該值:

Version < 7
int value;
if (int.TryParse(input, out value)) 
{
    Foo(value); // ok
}
else
{
    Foo(value); // value is zero
}

Foo(value); // ok

在 C#7.0 中,你可以內聯傳遞給 out 引數的變數的宣告,從而無需單獨的變數宣告:

Version >= 7
if (int.TryParse(input, out var value)) 
{
    Foo(value); // ok
}
else
{
    Foo(value); // value is zero
}

Foo(value); // still ok, the value in scope within the remainder of the body

如果不需要函式在 out 中返回的某些引數,則可以使用 discard 運算子 _

p.GetCoordinates(out var x, out _); // I only care about x

out var 宣告可以與任何已有 out 引數的現有函式一起使用。函式宣告語法保持不變,並且不需要額外的要求來使函式與 out var 宣告相容。這個功能只是語法糖。

out var 宣告的另一個特性是它可以與匿名型別一起使用。

Version >= 7
var a = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var groupedByMod2 = a.Select(x => new
                                  {
                                      Source = x,
                                      Mod2 = x % 2
                                  })
                     .GroupBy(x => x.Mod2)
                     .ToDictionary(g => g.Key, g => g.ToArray());
if (groupedByMod2.TryGetValue(1, out var oddElements))
{
    Console.WriteLine(oddElements.Length);
}

在此程式碼中,我們使用 int 鍵和匿名型別值陣列建立 Dictionary。在之前的 C#版本中,這裡不可能使用 TryGetValue 方法,因為它要求你宣告 out 變數(它是匿名型別!)。但是,使用 out var,我們不需要明確指定 out 變數的型別。

限制

請注意,out var 宣告在 LINQ 查詢中的用途有限,因為表示式被解釋為表示式 lambda 體,因此引入的變數的範圍僅限於這些 lambdas。例如,以下程式碼將不起作用:

var nums = 
    from item in seq
    let success = int.TryParse(item, out var tmp)
    select success ? tmp : 0; // Error: The name 'tmp' does not exist in the current context

參考