-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Convert/deconstruct in async-foreach only if TryGetNext succeeded #30258
Copy link
Copy link
Closed
Description
Should also cover nested deconstruction (with Deconstruct and with tuples).
[Fact]
public void TestWithExplicitlyConvertibleElementType()
{
string source = @"
using static System.Console;
using System.Threading.Tasks;
class C
{
public static async System.Threading.Tasks.Task Main()
{
foreach await (Element i in new C())
{
Write($""Got({i}) "");
}
}
public AsyncEnumerator GetAsyncEnumerator()
{
return new AsyncEnumerator();
}
public sealed class AsyncEnumerator : System.IAsyncDisposable
{
int i = 0;
public int TryGetNext(out bool found)
{
Write($""Next({i}) "");
found = i % 10 % 3 != 0;
return found ? i++ : 0;
}
public async Task<bool> WaitForNextAsync()
{
Write($""NextAsync({i}) "");
i = i + 11;
bool more = await Task.FromResult(i < 30);
return more;
}
public async ValueTask DisposeAsync()
{
Write($""Dispose({i}) "");
await Task.Delay(10);
}
}
}
class Element
{
int i;
public static explicit operator Element(int value) { Write($""Convert({value}) ""); return new Element(value); }
private Element(int value) { i = value; }
public override string ToString() => i.ToString();
}";
var comp = CreateCompilationWithTasksExtensions(source + s_interfaces, options: TestOptions.DebugExe);
comp.VerifyDiagnostics( );
// PROTOTYPE(async-streams) Convert(0) is here because we're converting the result even if TryGetNext returned false
CompileAndVerify(comp, expectedOutput: "NextAsync(0) Next(11) Convert(11) Got(11) Next(12) Convert(12) Got(12) " +
"Next(13) Convert(0) NextAsync(13) Next(24) Convert(24) Got(24) Next(25) Convert(25) Got(25) " +
"Next(26) Convert(0) NextAsync(26) Dispose(37)", verify: Verification.Skipped);
}Reactions are currently unavailable