Currently var can only be used in cases where the declaration and assignment are linked. It would be great (imo) if var could be used even if those statements weren't linked but was still verifiable by the compiler (not looking for dynamic here or anything like that).
This would be great for cases like the following silly example:
Before:
``` C#
IQueryable
if (SimpleQuery)
{
query = from p in Context.Query
select new PersonViewModel { Person = p };
}
else
{
query = from p in Context.Query
select new PersonViewModel { Person = p, Friends = p.Friends };
}
After:
``` C#
var query;
if (SimpleQuery)
{
query = from p in Context.Query<Person>
select new PersonViewModel { Person = p };
}
else
{
query = from p in Context.Query<Person>
select new PersonViewModel { Person = p, Friends = p.Friends };
}
It would be even more awesome if the compiler could infer even more - maybe using some structural typing when generating the anonymous, like:
C#
var query;
if (SimpleQuery)
{
query = from p in Context.Query<Person>
select new { Person = p };
}
else
{
query = from p in Context.Query<Person>
select new { Person = p, Friends = p.Friends };
}
The example you provide can be easily simplified with the use of the ?: operator.
var query = from p in Context.Query<Person>
select SimpleQuery ?
new PersonViewModel { Person = p } :
new PersonViewModel { Person = p, Friends = p.Friends };
That said there are cases where it could be useful, such as in try - catch - finally blocks, but it would have some unpleasant consequences. For instance, the type of the variable cannot be referred to until it has been assigned. Also, the type becomes path dependent so the compiler would need to do flow analysis to make sure that all possible assignments resolve to the same type.
Yeah - the example was certainly the most simple version and could be replaced with ?:, but you can imagine much more complex versions, try/catch as you mentioned, usings, multiple ifs, switch statements, etc.
Why couldn't the type of the variable be referred to? The variable isn't dynamic - it would still be statically known through some compiler magic ;) -- hopefully only needing limited flow analysis over what is currently done for var. And any case the compiler didn't want to support (because of complexity or whatnot) it could just issue an error that var couldn't be used in that case.
While I think the simple var case is nice, my guess the bang for the buck wouldn't necessarily pay off (but wanted to raise it as it would be nice and who knows might be easy). Though I think the really valuable feature would be "structural" typing with anonymous objects. That imo would be a huge win and isn't just syntactical sugar.
@eamodio
To your first point:
Yes, there are indeed more cases than just try - catch - finally, an expression form of pattern matching would solve most of these issues (see below).
To your second point:
var does not need to use flow analysis as it currently stands. It simply infers the type of the variable as the type of whatever expression is on the right hand of the =. I agree it has nothing to do with dynamic typing. I was suggesting the flow analysis would be complex, especially for tools like intellisense.
To your third point:
I think some form of structural typing would be great. The current proposals for tuples, which are expected to have nameable components, might give just this functionality. Also, the proposal for pattern matching, which currently includes property pattern matching, would also benefit in this area.
You can't use var with unsafe code either.
fixed (var* ptr = "abc")
{
ptr[0] = 'A';
}
Also consider var on fields.
Issue moved to dotnet/csharplang #520 via ZenHub
Most helpful comment
Also consider
varon fields.