Skip to content

Instantly share code, notes, and snippets.

@cezarypiatekGC
Created November 15, 2020 13:47
Show Gist options
  • Save cezarypiatekGC/358f15a3837fd03f0c3173cf891cc97b to your computer and use it in GitHub Desktop.
Save cezarypiatekGC/358f15a3837fd03f0c3173cf891cc97b to your computer and use it in GitHub Desktop.
public struct DisposableOwner<T> : IDisposable where T : IDisposable
{
private T _owned;
private bool _isReleased;
public DisposableOwner(T owned) => (_owned, _isReleased) = (owned, false);
public T Release()
{
if (_isReleased)
{
throw new InvalidOperationException("The ownership has been already released");
}
this._isReleased = true;
return _owned;
}
public void Dispose()
{
if (_isReleased == false)
{
_owned.Dispose();
}
}
}
public struct AsyncDisposableOwner<T> : IAsyncDisposable where T : IAsyncDisposable
{
private T _owned;
private bool _isReleased;
public AsyncDisposableOwner(T owned) => (_owned, _isReleased) = (owned, false);
public T Release()
{
if (_isReleased)
{
throw new InvalidOperationException("The ownership has been already released");
}
this._isReleased = true;
return _owned;
}
public async ValueTask DisposeAsync()
{
if (_isReleased == false)
{
await _owned.DisposeAsync();
}
}
}
public static class DisposableOwnerExtensions
{
public static DisposableOwner<T> TakeOwnership<T>(this T disposable) where T : IDisposable => new DisposableOwner<T>(disposable);
public static AsyncDisposableOwner<T> TakeOwnershipAsync<T>(this T disposable) where T : IAsyncDisposable => new AsyncDisposableOwner<T>(disposable);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment