2018-03-28 22:38:04 -04:00
using System ;
using System.Runtime.InteropServices ;
namespace Vanara.InteropServices
{
/// <summary>A safe variable to hold an instance of a COM class that automatically calls <see cref="Marshal.ReleaseComObject(object)"/> on disposal.</summary>
/// <typeparam name="T">The type of the COM object.</typeparam>
/// <seealso cref="System.IDisposable"/>
public class ComReleaser < T > : IDisposable where T : class
{
/// <summary>Initializes a new instance of the <see cref="ComReleaser{T}"/> class.</summary>
/// <param name="obj">The COM object instance.</param>
/// <exception cref="ArgumentNullException">obj</exception>
/// <exception cref="ArgumentException">Argument value must be a COM object. - obj</exception>
public ComReleaser ( T obj )
{
2018-03-30 13:53:21 -04:00
if ( obj = = null ) throw new ArgumentNullException ( nameof ( obj ) ) ;
2018-03-28 22:38:04 -04:00
if ( ! obj . GetType ( ) . IsCOMObject ) throw new ArgumentException ( "Argument value must be a COM object." , nameof ( obj ) ) ;
Item = obj ;
}
2018-03-30 13:53:21 -04:00
/// <summary>Initializes a new instance of the <see cref="ComReleaser{T}"/> class.</summary>
/// <param name="obj">The COM object instance.</param>
/// <exception cref="ArgumentNullException">obj</exception>
/// <exception cref="ArgumentException">Argument value must be a COM object and expose <typeparamref name="T"/>.</exception>
public ComReleaser ( object 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 is T t ? t : throw new ArgumentException ( $"Object must expose the {typeof(T).Name} interface." ) ;
}
2018-03-28 22:38:04 -04:00
/// <summary>Gets the COM object.</summary>
/// <value>The COM object.</value>
public T Item { get ; private set ; }
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
public void Dispose ( )
{
if ( Item = = null ) return ;
Marshal . FinalReleaseComObject ( Item ) ;
Item = null ;
}
2018-04-03 20:35:18 -04:00
/// <summary>Performs an implicit conversion from <see cref="ComReleaser{T}"/> to <typeparamref name="T"/>.</summary>
2018-03-28 22:38:04 -04:00
/// <param name="co">The <see cref="ComReleaser{T}"/> instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator T ( ComReleaser < T > co ) = > co . Item ;
2018-03-30 13:53:21 -04:00
2018-04-03 20:35:18 -04:00
/// <summary>Performs an implicit conversion from <typeparamref name="T"/> to <see cref="ComReleaser{T}"/>.</summary>
2018-03-30 13:53:21 -04:00
/// <param name="obj">The COM object.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator ComReleaser < T > ( T obj ) = > new ComReleaser < T > ( obj ) ;
2018-03-28 22:38:04 -04:00
}
}