Skip to content

Instantly share code, notes, and snippets.

@jammycakes
Last active December 26, 2022 22:31
Show Gist options
  • Save jammycakes/4452342 to your computer and use it in GitHub Desktop.
Save jammycakes/4452342 to your computer and use it in GitHub Desktop.
A subclass of System.Lazy<T> that implements IDisposable and forwards calls to the Dispose method on to the lazily created instance if it exists.
/// <summary>
/// A <see cref="Lazy"/> object that implements <see cref="IDisposable"/>.
/// </summary>
/// <typeparam name="T">
/// The object being lazily created.
/// </typeparam>
public class LazyDisposable<T> : Lazy<T>, IDisposable where T: IDisposable
{
/// <summary>
/// Initializes a new instance of the <see cref="LazyDisposable<T>"/> class.
/// When lazy initialization occurs, the default constructor is used.
/// </summary>
public LazyDisposable() : base() { }
/// <summary>
/// Initializes a new instance of the <see cref="LazyDisposable<T>"/> class.
/// When lazy initialization occurs, the default constructor of the target type
/// and the specified initialization mode are used.
/// </summary>
/// <param name="isThreadSafe">
/// true to make this instance usable concurrently by multiple threads;
/// false to make the instance usable by only one thread at a time.
/// </param>
public LazyDisposable(bool isThreadSafe) : base(isThreadSafe) { }
/// <summary>
/// Initializes a new instance of the <see cref="LazyDisposable<T>"/> class
/// that uses the default constructor of T and the specified thread-safety mode.
/// </summary>
/// <param name="mode">
/// One of the enumeration values that specifies the thread safety mode.
/// </param>
public LazyDisposable(LazyThreadSafetyMode mode) : base(mode) { }
/// <summary>
/// Initializes a new instance of the <see cref="LazyDisposable<T>"/> class.
/// When lazy initialization occurs, the specified initialization function is used.
/// </summary>
/// <param name="valueFactory">
/// The delegate that is invoked to produce the lazily initialized value when it is needed.
/// </param>
public LazyDisposable(Func<T> valueFactory) : base(valueFactory) { }
/// <summary>
/// Initializes a new instance of the <see cref="LazyDisposable<T>"/> class.
/// When lazy initialization occurs, the specified initialization function
/// and initialization mode are used.
/// </summary>
/// <param name="valueFactory">
/// The delegate that is invoked to produce the lazily initialized value when it is needed.
/// </param>
/// <param name="isThreadSafe">
/// true to make this instance usable concurrently by multiple threads;
/// false to make this instance usable by only one thread at a time.
/// </param>
public LazyDisposable(Func<T> valueFactory, bool isThreadSafe) : base(valueFactory, isThreadSafe) { }
/// <summary>
/// Initializes a new instance of the <see cref="LazyDisposable<T>"/> class
/// using the specified initialization function and thread-safety mode.
/// </summary>
/// <param name="valueFactory">
/// The delegate that is invoked to produce the lazily initialized value when it is needed.
/// </param>
/// <param name="mode">
/// One of the enumeration values that specifies the thread safety mode.
/// </param>
public LazyDisposable(Func<T> valueFactory, LazyThreadSafetyMode mode) : base(valueFactory, mode) { }
/// <summary>
/// Performs tasks defined in the created instance associated with freeing, releasing,
/// or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (this.IsValueCreated) this.Value.Dispose();
}
}
@HaukiDog
Copy link

HaukiDog commented May 6, 2022

Thanks.

A helper is another option:

public static class LazyHelpers
    {
        public static void Dispose<T>(this Lazy<T> @this)
               where T : IDisposable
        {
            if (@this?.IsValueCreated ?? false)
            {
                @this.Value.Dispose();
            }
        }
    }

@sysulincn
Copy link

Thanks.

A helper is another option:

public static class LazyHelpers
    {
        public static void Dispose<T>(this Lazy<T> @this)
               where T : IDisposable
        {
            if (@this?.IsValueCreated ?? false)
            {
                @this.Value.Dispose();
            }
        }
    }

extension method don't help in using statement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment