-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
[API Proposal]: Allow method built with an AsyncMethodBuilder to return something else than T #95472
Comments
Tagging subscribers to this area: @dotnet/area-system-threading-tasks Issue DetailsBackground and motivationWhen you implement a custom "Async Method Builder" to create your own instance of But, we could perfectly imagine cases where we can create a My uses case is where
API ProposalA method that uses an async method builder should accept that the user return any type for which there is a namespace MyLibrary;
[AsyncMethodBuilder(typeof(MyTaskMethodBuilder<>))]
public class MyTask<T>
{
public void SetResult(T? value) { }
public void SetResult(Option<T> value) { }
public void SetException(Exception error) { }
}
public enum OptionType
{
None,
Some,
}
public record struct Option<T>(OptionType Type, T? Value)
{
public static Option<T> Some(T value) => new(OptionType.Some, value);
public static Option<T> None() => new(OptionType.None, default);
}
[EditorBrowsable(EditorBrowsableState.Never)]
public readonly struct MyTaskMethodBuilder<T>
{
private readonly MyTask<T> _task = new();
public MyTaskMethodBuilder() { }
public MyTask<T> Task => _task;
public static FeedMethodBuilder<T> Create()
=> new();
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
=> stateMachine.MoveNext();
public void SetStateMachine(IAsyncStateMachine stateMachine) { }
public void SetException(Exception exception)
=> _task.SetException(exception);
public void SetResult(T? result)
=> _task.SetResult(result);
public void SetResult(Option<T> result)
=> _task.SetResult(result);
public void AwaitOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
=> awaiter.OnCompleted(stateMachine.MoveNext);
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
=> awaiter.OnCompleted(stateMachine.MoveNext);
} API Usagenamespace MyUserApp;
public class MyUserClass
{
public async MyTask<int> WhenReturnInt() => 42;
public async MyTask<int> WhenReturnNullableInt() => default(int?);
public async MyTask<int> WhenReturnOption() => Option<int>.None();
} Alternative DesignsTwo alternatives are possible:
Risks
|
This seems like a C# language feature. You should open an issue in https://github.com/dotnet/csharplang instead. |
Thanks @teo-tsirpanis, I was not sure but since I found the |
Background and motivation
When you implement a custom "Async Method Builder" to create your own instance of
MyTask<T>
the single type that the user can return in the function isT
.But, we could perfectly imagine cases where we can create a
MyTask<T>
with something else thanT
, for instance aT?
(or a customOption<T>
).My uses case is where
MyTask<T>
will implementIOtherInterface<GenericType<T>>
. Restricting async method builder to onlyT
means either:MyTask<GenericType<T>>
, which not possible sinceMyTask
must have only one 1 type parameter, we cannot have type constraints onMyTask<T> where T : GenericType<T???>
;GenericType<T>
toT
but this will result in a lost of information.API Proposal
A method that uses an async method builder should accept that the user return any type for which there is a
SetResult
on the builder.API Usage
Alternative Designs
Two alternatives are possible:
SetResult
on the builder", we could support only one type (e.g.SetResult(Option<T> result)
- as an implicit cast fromT
toOption<T>
is possible here).SetResult
accepts it (i.e.SetResult(T? result)
).Risks
The text was updated successfully, but these errors were encountered: