Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support the use of var in more cases #2114

Closed
eamodio opened this issue Apr 20, 2015 · 6 comments
Closed

Support the use of var in more cases #2114

eamodio opened this issue Apr 20, 2015 · 6 comments

Comments

@eamodio
Copy link

eamodio commented Apr 20, 2015

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:

IQueryable<PersonViewModel> 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 };
}

After:

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:

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 };
}
@aluanhaddad
Copy link

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.

@eamodio
Copy link
Author

eamodio commented Apr 22, 2015

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.

@aluanhaddad
Copy link

@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.

@GeirGrusom
Copy link

You can't use var with unsafe code either.

fixed (var* ptr = "abc")
{
  ptr[0] = 'A';
}

@GSPP
Copy link

GSPP commented Oct 25, 2015

Also consider var on fields.

@gafter
Copy link
Member

gafter commented Apr 28, 2017

Issue moved to dotnet/csharplang #520 via ZenHub

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants