[dotnet][bidi] fix CS0121 ambiguous ConfigureAwait on IEventStream<T>#17711
[dotnet][bidi] fix CS0121 ambiguous ConfigureAwait on IEventStream<T>#17711Chandan25sharma wants to merge 1 commit into
Conversation
Problem
-------
IEventStream<T> inherits both IAsyncEnumerable<T> and IAsyncDisposable.
System.Linq.Async ships a ConfigureAwait overload for each of those
interfaces in TaskAsyncEnumerableExtensions:
ConfigureAwait<T>(IAsyncEnumerable<T>, bool) -> ConfiguredCancelableAsyncEnumerable<T>
ConfigureAwait(IAsyncDisposable, bool) -> ConfiguredAsyncDisposable
Both overloads match when the receiver is an IEventStream<T>, so the
compiler emits CS0121 ("The call is ambiguous between ..."). Users had
to add an explicit cast to either interface to work around this, which
is both surprising and hard to discover.
Fix
---
Add EventStreamExtensions.ConfigureAwait<T>(this IEventStream<T>, bool)
that explicitly delegates to the IAsyncEnumerable<T> overload. Because
a more-derived receiver type takes priority over the two BCL overloads,
the compiler now resolves the call unambiguously without any cast at the
call site. The IAsyncEnumerable<T> variant is the correct choice here
since callers use ConfigureAwait to control context capture inside
`await foreach` loops, not during disposal.
Testing
-------
EventStreamExtensionsTests verifies at the type level that the return
type is ConfiguredCancelableAsyncEnumerable<T> (not ConfiguredAsyncDisposable)
and at the behavioural level that events flow through a
ConfigureAwait(false) enumeration correctly.
Fixes: SeleniumHQ#17696
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PR Summary by QodoFix CS0121 ConfigureAwait ambiguity for BiDi IEventStream Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo
Context used✅ Compliance rules (platform):
15 rules 1. Public EventStreamExtensions lacks <summary>
|
| namespace OpenQA.Selenium.BiDi; | ||
|
|
||
| public static class EventStreamExtensions | ||
| { |
There was a problem hiding this comment.
1. Public eventstreamextensions lacks
📘 Rule violation ✧ Quality
The new public type EventStreamExtensions is introduced without an XML documentation comment containing a non-empty <summary>, which violates the requirement for documenting all public API members. Missing docs reduce API discoverability and can break documentation generation pipelines.
Agent Prompt
## Issue description
A new public API type `EventStreamExtensions` is missing an XML doc comment with a non-empty `<summary>` immediately preceding the declaration.
## Issue Context
The compliance checklist requires XML documentation with `<summary>` for all public types and members introduced or modified in the diff.
## Fix Focus Areas
- dotnet/src/webdriver/BiDi/EventStreamExtensions.cs[22-25]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
On hold. This extension method doesn't resolve the issue. Why Potentially would be resolved by #17705 |
Problem
IEventStream inherits both IAsyncEnumerable and IAsyncDisposable. System.Linq.Async ships a ConfigureAwait overload for each of those interfaces in TaskAsyncEnumerableExtensions:
ConfigureAwait(IAsyncEnumerable, bool) -> ConfiguredCancelableAsyncEnumerable
ConfigureAwait(IAsyncDisposable, bool) -> ConfiguredAsyncDisposable
Both overloads match when the receiver is an IEventStream, so the compiler emits CS0121 ("The call is ambiguous between ..."). Users had to add an explicit cast to either interface to work around this, which is both surprising and hard to discover.
Fix
Add EventStreamExtensions.ConfigureAwait(this IEventStream, bool) that explicitly delegates to the IAsyncEnumerable overload. Because a more-derived receiver type takes priority over the two BCL overloads, the compiler now resolves the call unambiguously without any cast at the call site. The IAsyncEnumerable variant is the correct choice here since callers use ConfigureAwait to control context capture inside
await foreachloops, not during disposal.Testing
EventStreamExtensionsTests verifies at the type level that the return type is ConfiguredCancelableAsyncEnumerable (not ConfiguredAsyncDisposable) and at the behavioural level that events flow through a ConfigureAwait(false) enumeration correctly.
Fixes: #17696