namespace Vanara.InteropServices; /// Factory for creating objects. public static class ComReleaserFactory { /// Factory method to create a using type inference. /// The type of the object. /// The object. /// A instance. public static ComReleaser Create(TObj obj) where TObj : class => new(obj); } /// A safe variable to hold an instance of a COM class that automatically releases the instance on disposal. /// The type of the COM object. /// public class ComReleaser : IDisposable where T : class { private T? item; /// Initializes a new instance of the class. /// The COM object instance. /// obj /// Argument value must be a COM object. - obj public ComReleaser(T obj) { if (obj == null) throw new ArgumentNullException(nameof(obj)); if (!obj.GetType().IsCOMObject) throw new ArgumentException("Argument value must be a COM object.", nameof(obj)); item = obj; } /// Initializes a new instance of the class. /// The COM object instance. /// obj /// Argument value must be a COM object and expose . public ComReleaser(object obj) { if (!obj.GetType().IsCOMObject) throw new ArgumentException("Argument value must be a COM object.", nameof(obj)); item = obj is T t ? t : throw new ArgumentException($"Object must expose the {typeof(T).Name} interface."); } /// Gets the COM object. /// The COM object. public T Item => item ?? throw new ObjectDisposedException(nameof(ComReleaser)); /// Performs an implicit conversion from to . /// The COM object. /// The result of the conversion. public static explicit operator ComReleaser(T obj) => new(obj); /// Performs an implicit conversion from to . /// The instance. /// The result of the conversion. public static explicit operator T(ComReleaser co) => co.Item; /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. public void Dispose() => item = null; }