C#out var声明

示例

C#中的一种常见模式用于安全地解析对象。bool TryParse(object input, out object value)

该out var声明是一个简单的功能,以提高可读性。它允许在将变量作为out参数传递的同时声明该变量。

以这种方式声明的变量在声明它的点处作用于主体的其余部分。

示例

使用TryParseC#7.0之前的版本,必须在调用函数之前声明一个变量以接收值:

7.0
int value;
if (int.TryParse(input, out value)) 
{
    Foo(value); // 好
}
else
{
    Foo(value); // 值为零
}

Foo(value); // 好

在C#7.0中,可以内联传递给该out参数的变量的声明,从而无需单独的变量声明:

7.0
if (int.TryParse(input, out var value)) 
{
    Foo(value); // 好
}
else
{
    Foo(value); // 值为零
}

Foo(value); // 仍然可以,其余主体的范围内的值

如果out不需要某个函数返回的某些参数,则可以使用抛弃运算符_。

p.GetCoordinates(out var x, out _); // 我只在乎x

一个out var声明可以与已经具有任何现有的功能中使用out的参数。函数声明语法保持不变,并且不需要其他要求即可使函数与out var声明兼容。此功能只是语法糖。

out var声明的另一个功能是它可以与匿名类型一起使用。

7.0
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);
}

在这段代码中,我们创建一个Dictionary带有int键和匿名类型值的数组。在C#的早期版本中,TryGetValue此处无法使用method,因为它要求您声明out变量(匿名类型!)。但是,out var我们不需要显式地指定out变量的类型。

局限性

请注意,由于表达式被解释为表达式lambda主体,因此out var声明在LINQ查询中使用有限,因此引入的变量的范围仅限于这些lambda。例如,以下代码将不起作用:

var nums = 
    from item in seq
    let success = int.TryParse(item, out var tmp)
    select success ? tmp : 0; // 错误:名称“ tmp”在当前上下文中不存在

参考文献

  • 在GitHub上原始的var声明提案