0

我有一个通用基类,它包装 COM 对象并希望将其限制为 COM 对象。我试过where TComObject : IUnknown了,但编译器不喜欢它。有没有办法做到这一点?

我使用下面的代码,如果您发现一些愚蠢的东西,请提供反馈。

public abstract class ComWrapper<TComObject> : IDisposable, IComWrapper<TComObject> where TComObject : class 
{
    protected ComWrapper(TComObject comObject)
    {
        ComObject = comObject;
    }

    protected TComObject ComObject { get; set; }

    /// <summary>
    /// Use with caution, this accesses the COM object, cleanup might be needed
    /// </summary>
    /// <returns></returns>
    public TComObject GetComObject()
    {
        return ComObject;
    }

    public void SetComObject(TComObject comObject)
    {
        CheckAndReleaseComObject();
        ComObject=comObject;
    }

    public void Dispose()
    {
        Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // free managed resources
        }
        // free native resources if there are any.
        CheckAndReleaseComObject();
    }

    private void CheckAndReleaseComObject()
    {
        if (ComObject != null)
        {
            if (ComObject.GetType().IsCOMObject)
                Marshal.ReleaseComObject(ComObject);
            ComObject = null;
        }
    }
}
4

1 回答 1

1

您不能设置这样的通用约束,但是,您可以考虑使用类似Marshal.IsComObject的东西来确保对象是 COM 对象。如果您特别想要编译时错误,我认为您不走运。

另外,请注意 SetComObject 可以被多次调用,在这种情况下,您不会“清理”任何可能已经设置的 com 对象。此外,您现在可以删除 GC.SuppressFinalize,因为您删除了终结器/析构函数,这确实是不需要的,因为如果 com 对象进入垃圾收集,框架将为您释放它。

于 2012-11-01T09:36:40.177 回答