Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
URL Rewriter Bot
URL Rewriter Bot

When using lambda expressions or anonymous methods in C#, we have to be wary of the access to modified closure pitfall. For example:

foreach (var s in strings) { query = query.Where(i => i.Prop == s); // access to modified closure ... } 

Due to the modified closure, the above code will cause all of the Where clauses on the query to be based on the final value of s.

As explained here, this happens because the s variable declared in foreach loop above is translated like this in the compiler:

string s; while (enumerator.MoveNext()) { s = enumerator.Current; ... } 

instead of like this:

while (enumerator.MoveNext()) { string s; s = enumerator.Current; ... } 

As pointed out herehere, there are no performance advantages to declaring a variable outside the loop, and under normal circumstances the only reason I can think of for doing this is if you plan to use the variable outside the scope of the loop:

string s; while (enumerator.MoveNext()) { s = enumerator.Current; ... } var finalString = s; 

However variables defined in a foreach loop cannot be used outside the loop:

foreach(string s in strings) { } var finalString = s; // won't work: you're outside the scope. 

So the compiler declares the variable in a way that makes it highly prone to an error that is often difficult to find and debug, while producing no perceivable benefits.

Is there something you can do with foreach loops this way that you couldn't if they were compiled with an inner-scoped variable, or is this just an arbitrary choice that was made before anonymous methods and lambda expressions were available or common, and which hasn't been revised since then?

When using lambda expressions or anonymous methods in C#, we have to be wary of the access to modified closure pitfall. For example:

foreach (var s in strings) { query = query.Where(i => i.Prop == s); // access to modified closure ... } 

Due to the modified closure, the above code will cause all of the Where clauses on the query to be based on the final value of s.

As explained here, this happens because the s variable declared in foreach loop above is translated like this in the compiler:

string s; while (enumerator.MoveNext()) { s = enumerator.Current; ... } 

instead of like this:

while (enumerator.MoveNext()) { string s; s = enumerator.Current; ... } 

As pointed out here, there are no performance advantages to declaring a variable outside the loop, and under normal circumstances the only reason I can think of for doing this is if you plan to use the variable outside the scope of the loop:

string s; while (enumerator.MoveNext()) { s = enumerator.Current; ... } var finalString = s; 

However variables defined in a foreach loop cannot be used outside the loop:

foreach(string s in strings) { } var finalString = s; // won't work: you're outside the scope. 

So the compiler declares the variable in a way that makes it highly prone to an error that is often difficult to find and debug, while producing no perceivable benefits.

Is there something you can do with foreach loops this way that you couldn't if they were compiled with an inner-scoped variable, or is this just an arbitrary choice that was made before anonymous methods and lambda expressions were available or common, and which hasn't been revised since then?

When using lambda expressions or anonymous methods in C#, we have to be wary of the access to modified closure pitfall. For example:

foreach (var s in strings) { query = query.Where(i => i.Prop == s); // access to modified closure ... } 

Due to the modified closure, the above code will cause all of the Where clauses on the query to be based on the final value of s.

As explained here, this happens because the s variable declared in foreach loop above is translated like this in the compiler:

string s; while (enumerator.MoveNext()) { s = enumerator.Current; ... } 

instead of like this:

while (enumerator.MoveNext()) { string s; s = enumerator.Current; ... } 

As pointed out here, there are no performance advantages to declaring a variable outside the loop, and under normal circumstances the only reason I can think of for doing this is if you plan to use the variable outside the scope of the loop:

string s; while (enumerator.MoveNext()) { s = enumerator.Current; ... } var finalString = s; 

However variables defined in a foreach loop cannot be used outside the loop:

foreach(string s in strings) { } var finalString = s; // won't work: you're outside the scope. 

So the compiler declares the variable in a way that makes it highly prone to an error that is often difficult to find and debug, while producing no perceivable benefits.

Is there something you can do with foreach loops this way that you couldn't if they were compiled with an inner-scoped variable, or is this just an arbitrary choice that was made before anonymous methods and lambda expressions were available or common, and which hasn't been revised since then?

edited tags
Link
Erik Kaplun
  • 38.5k
  • 15
  • 102
  • 113
added 87 characters in body
Source Link
StriplingWarrior
  • 157.5k
  • 29
  • 261
  • 326

When using lambda expressions or anonymous methods in C#, we have to be wary of the access to modified closure pitfall. For example:

foreach (var s in strings) { query = query.Where(i => i.Prop == s); // access to modified closure  ... } 

Due to the modified closure, the above code will cause all of the Where clauses on the query to be based on the final value of s.

As explained here, this happens because the s variable declared in foreach loop above is translated like this in the compiler:

string s; while (enumerator.MoveNext()) { s = enumerator.Current; ... } 

instead of like this:

while (enumerator.MoveNext()) { string s; s = enumerator.Current; ... } 

As pointed out here, there are no performance advantages to declaring a variable outside the loop, and under normal circumstances the only reason I can think of for doing this is if you plan to use the variable outside the scope of the loop:

string s; while (enumerator.MoveNext()) { strings s;= enumerator.Current; ... } var finalString = s; 

However variables defined in a foreach loop cannot be used outside the loop:

foreach(string s in strings) { } var finalString = s; // won't work: you're outside the scope. 

So the compiler declares the variable in a way that makes it highly prone to an error that is often difficult to find and debug, while producing no perceivable benefits.

Is there something you can do with foreach loops this way that you couldn't if they were compiled with an inner-scoped variable, or is this just an arbitrary choice that was made before anonymous methods and lambda expressions were available or common, and which hasn't been revised since then?

When using lambda expressions or anonymous methods in C#, we have to be wary of the access to modified closure pitfall. For example:

foreach (var s in strings) { query = query.Where(i => i.Prop == s); // access to modified closure } 

Due to the modified closure, the above code will cause all of the Where clauses on the query to be based on the final value of s.

As explained here, this happens because the s variable declared in foreach loop above is translated like this in the compiler:

string s; while (enumerator.MoveNext()) { s = enumerator.Current; ... } 

instead of like this:

while (enumerator.MoveNext()) { string s; s = enumerator.Current; } 

As pointed out here, there are no performance advantages to declaring a variable outside the loop, and under normal circumstances the only reason I can think of for doing this is if you plan to use the variable outside the scope of the loop:

while() { string s; } var finalString = s; 

However variables defined in a foreach loop cannot be used outside the loop:

foreach(string s in strings) { } var finalString = s; // won't work: you're outside the scope. 

So the compiler declares the variable in a way that makes it highly prone to an error that is often difficult to find and debug, while producing no perceivable benefits.

Is there something you can do with foreach loops this way that you couldn't if they were compiled with an inner-scoped variable, or is this just an arbitrary choice that was made before anonymous methods and lambda expressions were available or common, and which hasn't been revised since then?

When using lambda expressions or anonymous methods in C#, we have to be wary of the access to modified closure pitfall. For example:

foreach (var s in strings) { query = query.Where(i => i.Prop == s); // access to modified closure  ... } 

Due to the modified closure, the above code will cause all of the Where clauses on the query to be based on the final value of s.

As explained here, this happens because the s variable declared in foreach loop above is translated like this in the compiler:

string s; while (enumerator.MoveNext()) { s = enumerator.Current; ... } 

instead of like this:

while (enumerator.MoveNext()) { string s; s = enumerator.Current; ... } 

As pointed out here, there are no performance advantages to declaring a variable outside the loop, and under normal circumstances the only reason I can think of for doing this is if you plan to use the variable outside the scope of the loop:

string s; while (enumerator.MoveNext()) { s = enumerator.Current; ... } var finalString = s; 

However variables defined in a foreach loop cannot be used outside the loop:

foreach(string s in strings) { } var finalString = s; // won't work: you're outside the scope. 

So the compiler declares the variable in a way that makes it highly prone to an error that is often difficult to find and debug, while producing no perceivable benefits.

Is there something you can do with foreach loops this way that you couldn't if they were compiled with an inner-scoped variable, or is this just an arbitrary choice that was made before anonymous methods and lambda expressions were available or common, and which hasn't been revised since then?

added 43 characters in body
Source Link
abatishchev
  • 100.7k
  • 88
  • 304
  • 443
Loading
Question Protected by Mayank K. Swami
improved formatting
Source Link
Omar
  • 16.7k
  • 10
  • 53
  • 69
Loading
added 127 characters in body
Source Link
StriplingWarrior
  • 157.5k
  • 29
  • 261
  • 326
Loading
edited tags
Link
BoltClock
  • 728.3k
  • 165
  • 1.4k
  • 1.4k
Loading
Source Link
StriplingWarrior
  • 157.5k
  • 29
  • 261
  • 326
Loading