CSharp · Console
#nullable enable
namespace NoItDoesNotGetCalled
{
using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
[AsyncMethodBuilder(typeof(CustomAwaitableAsyncMethodBuilder<>))]
public readonly struct CustomAwaitable<T>
{
readonly ValueTask<T> _valueTask;
public CustomAwaitable(ValueTask<T> valueTask)
{
_valueTask = valueTask;
}
public ValueTaskAwaiter<T> GetAwaiter() => _valueTask.GetAwaiter();
}
public struct CustomAwaitableAsyncMethodBuilder<T>
{
public CustomAwaitable<T> Task => default;
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.UnsafeOnCompleted(stateMachine.MoveNext);
public static CustomAwaitableAsyncMethodBuilder<T> Create() => default;
public void SetException(Exception exception) {}
public void SetResult(T result) {}
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
Console.WriteLine("Yet this doesn't happen :(");
}
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
if (typeof(TStateMachine).IsValueType)
{
Console.WriteLine("See? Here's a state machine that's implemented as a struct!");
}
stateMachine.MoveNext();
}
}
public class Program
{
public static async Task Main()
{
async CustomAwaitable<object?> GetValueAsync()
{
await Task.CompletedTask;
return null;
}
await GetValueAsync();
}
}
}