Table of Contents

Early Finally Functions for .NET / Unity

Runtime/System/Defer.cs   HeaderDoc

(c) 2024 Sator Imaging, Licensed under the MIT License https://github.com/sator-imaging/Unity-Fundamentals

How to Use

// try-finally pattern made simple
using var rental = ArrayPool<byte>.Shared.Rent(256)
    .Defer(static x =>
    {
        // this will be executed when exiting 'rental' variable scope
        ArrayPool<byte>.Shared.Return(x, clearArray: true);
    });

// 'Value' to access extension method receiver
var span = rental.Value.AsSpan();

// ex) restore temporary value to original
using var _ = foo.Defer(foo.Value, (x, restore) => x.Value = restore);
foo.Value = tempValue;

// ex) always rewind stream on exit
using var _ = stream.Defer(stream => stream.Position = 0);

// ex) achieve exlusive task using interlocked operation
if (Interlocked.Exchange(ref _foo, 1) != 0) return;
using var _ = Defer.New(() => Interlocked.Exchange(ref _foo, 0));

Note for use with using block statement.

var data = (name: "value tuple", value: 3.10f);
using (data.Defer(static x => Console.WriteLine($"Disposed: {x.name} ({x.value}")))
{
    Console.WriteLine("Disposing " + data.Value.name);
}

// note that 'data' still be accessible after Dispose() is called
// * block-less-using statement is recommended to make variable scope in sync
data.value = -310;