为什么在使用Linq时需要初始化out变量

时间:2016-09-04 15:24:40

标签: c# linq

假设我有一个我要转换为整数的字符串,我会这样做

int i;
int.TryParse(someString, out i);

现在我想在Linq查询中做同样的事情:

int i;
var numbers =
   from s in someStrings
   where int.TryParse(s, out i)
   select i;

但是这拒绝使用错误编译

  

CS0165使用未分配的本地变量' i'

当我将i初始化为任意值时,它会按预期编译和工作。但为什么我必须这样做?

3 个答案:

答案 0 :(得分:6)

查询表达式被翻译为:

var numbers = someStrings.Where(s => int.TryParse(s, out i))
                         .Select(s => i);

现在,我们知道从Where调用的lambda表达式创建的委托将在从Select调用的lambda表达式创建的委托之前执行,但是编译器并没有。事实上,你可以轻松编写自己的扩展方法,但不遵守:

public static IEnumerable<T> Where<T>(
    this IEnumerable<T> source,
    Func<T, bool> predicate)
{
    // I can't be bothered to check the predicate... let's just return everything
    return source;
}

此时,通过正常Select调用,您的代理返回i将被执行而不会为其分配值。

基本上,明确的分配规则是故意相当保守的,避免对做什么方法做出任何假设等。

答案 1 :(得分:3)

这将编译为传递给Where()Select()的一对lambda表达式。

编译器不知道Where()Select()做了什么,也无法证明Where()的lambda将始终在Select()之前运行。

答案 2 :(得分:-1)

编译器直到运行时才能确定是否会返回任何记录。因此,为了使i具有确定的值,必须明确指定一个值。试想一下,如果我的查询没有返回任何行,我会怎样?