Thomas Schremser Thomas Schremser - 1 year ago 61
C# Question

Why do I need to initialize an out variable when using Linq

Supposing I have a string which I want to convert to an integer, I would do

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

Now I would like to do the same in a Linq query:

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

But this refuses to compile with the error

CS0165 Use of unassigned local variable 'i'

It compiles and works as intended when I initialize i to an arbitraty value. But why do I have to?

Answer Source

The query expression is translated into:

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

Now, we know that the delegate created from the lambda expression for the Where call will be executed before the delegate created from the lambda expression for the Select call, but the compiler doesn't. And indeed, you could easily write your own extension method that didn't obey that:

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;

At that point, with the normal Select call, your delegate returning i would be executed without every assigning a value to it.

Basically, the definite assignment rules are deliberately quite conservative, avoiding making any assumptions about what methods do etc.