Roslyn fails to enforce definite assignment rule for a variable assigned in a local iterator function or local async function
See original GitHub issueRoslyn fails to enforce definite assignment rules for variables which are assigned in local iterator functions or local async functions which are called before the variables in question are used.
Since these types of local functions don’t execute all statements at the first call it can’t be proven that assignment was executed.
here are some examples:
- Since I don’t iterate the result of Local function it’s body won’t execute at all and I will end up using unassigned local variable i;
using System;
using System.Collections.Generic;
public class C
{
static void Main()
{
int i;
Local();
Console.WriteLine(i);
IEnumerable<int> Local()
{
yield return 0;
i = 10;
}
}
}
- This case even marks statement ‘i = 10;’ as unreachable but still allows to use the variable in the enclosing method.
using System;
using System.Collections.Generic;
public class C
{
static void Main()
{
int i;
Local();
Console.WriteLine(i);
IEnumerable<int> Local()
{
yield break;
i = 10;
}
}
}
- It’s almost guaranteed that local variable i won’t be assigned by the time it’s used.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public class C
{
static void Main()
{
int i;
Local();
Console.WriteLine(i);
async Task Local()
{
await Task.Delay(1000*60*60);
i = 10;
}
}
}
Issue Analytics
- State:
- Created 7 years ago
- Comments:7 (4 by maintainers)
Top Results From Across the Web
Definite assignment bug when not awaiting an async closure
The local function doesn't contain any await s itself, so it is guaranteed to execute fully even if you don't await it. If...
Read more >Exploring Roslyn, part 3: Breaking Changes - SLaks.Blog
Local variables in your method become fields in the iterator class, so they can be persisted across calls to MoveNext() .
Read more >c# - Cannot assign to item because it is a foreach iteration ...
c# - Cannot assign to item because it is a foreach iteration variable - Stack Overflow.
Read more >Lambda expressions
I'll cover ways to avoid mutating variables and data structures, passing functions as data, how LINQ is functional, and some speculation on ...
Read more >11 Efficiency and readability tweaks - C# in Depth, Fourth ...
The rules of definite assignment in C# are complicated, and local methods complicate them further. The simplest way to think about it is...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I’m going to disallow async and iterator functions from definitely assigning variables. The behavior is just too subtle.
Compiler data flow will be fixed to recognize these branches, though.
From: TessenR notifications@github.com Sent: Monday, September 19, 2016 5:20:36 AM To: dotnet/roslyn Cc: Andy Gocke; Mention Subject: Re: [dotnet/roslyn] Roslyn fails to enforce definite assignment rule for a variable assigned in a local iterator function or local async function (#13762)
@agockehttps://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fgithub.com%2fagocke&data=02%7c01%7cangocke%40microsoft.com%7ce4b40b9577cd43bd24d608d3e0875c9b%7c72f988bf86f141af91ab2d7cd011db47%7c1%7c0%7c636098844388392240&sdata=R5kRtLRZ4tu2pEx1gc582382uQ%2fuWoXPThf9iNB42Eg%3d Is there any decision how this should be implemented? I will appreciate any clarification about expected behavior.
I personally think that compiler should not propagate writes from iterator/async local functions at all.
However if you are planning to propagate writes from iterator/async local functions I’d like to know expected results for some other cases which also don’t have compiler errors currently.
using System.Linq; class C { void M() { int x,y;
}
You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fgithub.com%2fdotnet%2froslyn%2fissues%2f13762%23issuecomment-247978035&data=02%7c01%7cangocke%40microsoft.com%7ce4b40b9577cd43bd24d608d3e0875c9b%7c72f988bf86f141af91ab2d7cd011db47%7c1%7c0%7c636098844388402249&sdata=%2fFkJ2tCJJU5%2bKwl%2fTb9pqCL6IXxte6udiLa5Bb3isiU%3d, or mute the threadhttps://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fgithub.com%2fnotifications%2funsubscribe-auth%2fAAfevv0JVwiyv8cS5J-nv9fIDOS3jfN9ks5qrn4UgaJpZM4J8AnU&data=02%7c01%7cangocke%40microsoft.com%7ce4b40b9577cd43bd24d608d3e0875c9b%7c72f988bf86f141af91ab2d7cd011db47%7c1%7c0%7c636098844388402249&sdata=d800diVw339lAANdLRpvTWPD5eF8i7qMoBZB3EJVYsM%3d.
Probably the LINQ operator in VisualBasic combine with lambda can be more simplify