-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Champion "Permit expression variables everywhere" #1020
Comments
E.g.:
|
@HaloFour there's a missing paren in the first example |
var q =
from item in list
where item is int value
select value; |
@orthoxerox Fixed. Thanks. |
Please don't limit expression variables like this in LINQ. It's my opinion that the intuitive scope for variable expressions in a LINQ query would be the same for range variables. For var query1 = from text in strings
where int.TryParse(text, out int value)
select value;
// translated into
var query1 = strings
.Select(text => new {
text = text,
temp = int.TryParse(text, out int value),
value = value
})
.Where(projected => projected.temp)
.Select(projected => projected.value); For patterns it gets a little trickier only because the current definite assignment rules wouldn't allow the translation to compile unless the compiler made special considerations for the var q =
from item in list
where item is int value
select value;
// translated into
var q = list
.Select(item => new {
item = item,
temp = item is int value,
value = value //CS0165
})
.Where(projected => projected.temp)
.Select(projected => projected.value); There is the valid concern that implicitly allowing for these expression variables to escape the scope of the expression would produce even slower queries due to the additional calls to |
That almost works for a few kinds of query clauses. Even if it worked for all of them, for many users it would be an unacceptable performance penalty for something they do not want or need in their code. We intend to permit programmers to explicitly express their intent here, rather than automatically extending the scope and creating unwanted range variables by inserting implicit query clauses. See #189 . We'll do that by extending the from s in strings
let (isNumber, value) = (int.TryParse(s, out var v), v)
where isNumber
select value |
A little kludgy but at least it would enable that kind of functionality. For pattern matching scenarios I guess the developer would have to do the following: var q =
from item in list
let (success, value) = item is int value ? (true, value) : (false, 0)
where success
select value; What about resurrecting dotnet/roslyn#6400 and dotnet/roslyn#6877 to enable pattern-based destructuring in LINQ queries via the var q =
from item in list
let int value = item else continue
select value; |
Would it be possible to add the extra |
@svick I don't know whether it is possible because I haven't heard what people think should occur with any other than one or two kinds of clauses. I suppose we are all left to imagine how the others should behave. If it were possible, it would be much more complicated to specify, implement, and reason about than the current simple syntactic translation. |
How performance is a concern here? In that case, I think they wouldn't want to use linq in the first place (or use rewriters to eliminate allocations). I thought linq is all about syntactic transformation for the sake readability at the cost of a little magic and sometimes perf penalty? |
Closing in preference of #32 |
There are three contexts where out variable declarations and pattern matching variable declarations are not permitted today, in part because we did not decide what the scope should be. I propose we decide for each of these three contexts, and extend the language to permit declaration expressions in these contexts.
Constructor-initializers. The primary question is whether the scope of variables declared in a ctor-initializer extends to the constructor body or not. I propose that it should extend to the body.
Field initializers. The primary question is whether the scope of variables declared in the one equals-value-clause is in scope in subsequent equals-value-clauses of the same field declaration (when it declares more than one field). It is also possible to extend the scope to subsequent separate field declaration's initializers too, but I don't think that is likely to be approved by the LDM.
Query clauses. The primary question is what is the scope of variables declared in a query clause that is specified to be translated into the body of a lambda. One possible resolution is that its scope is just that expression of the clause.
The text was updated successfully, but these errors were encountered: