Go Playground - The Go Programming Language



using static Defer;
class Defer : Stack<Func<ValueTask>>, IAsyncDisposable
{
    async ValueTask IAsyncDisposable.DisposeAsync()
    { while(this.TryPop(out var func)) await func(); }
    static readonly System.Threading.AsyncLocal<Defer> local = new();
    public static Defer defer { get => local.Value ??= new(); set => local.Value = value; }

    public static Defer operator +(Defer a, Func<ValueTask> b) { a.Push(b); return a; }
    public static Defer operator +(Defer a, Action b) => a += async () => b();
}

_ = Task.Run(async ()=>
{
    await using var _ = defer;

    for(int i = 0; i < 5; i++)
    {
        var hello = string.Concat(Enumerable.Repeat("하이!", i));
        Console.WriteLine(hello);
        defer += () => Console.WriteLine(hello);
    }
});

{
    await using var _ = defer;

    for(int i = 0; i < 5; i++)
    {
        var hello = string.Concat(Enumerable.Repeat("헬로!", i));
        Console.WriteLine(hello);
        defer += () => Console.WriteLine(hello);
    }
}