C# COM对象的通用约束

C# COM对象的通用约束,c#,generics,com,dispose,C#,Generics,Com,Dispose,我有一个封装COM对象的通用基类,并希望将其约束到COM对象。 我尝试了其中TComObject:IUnknown,但编译器不喜欢它。有办法做到这一点吗 我使用下面的代码,如果你发现一些愚蠢的事情,请给出反馈 public abstract class ComWrapper<TComObject> : IDisposable, IComWrapper<TComObject> where TComObject : class { protected ComWrap

我有一个封装COM对象的通用基类,并希望将其约束到COM对象。 我尝试了
其中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;
        }
    }
}
公共抽象类ComWrapper:IDisposable,IComWrapper其中TComObject:class
{
受保护的ComWrapper(TComObject comObject)
{
ComObject=ComObject;
}
受保护的TComObject对象{get;set;}
/// 
///请小心使用,这会访问COM对象,可能需要清理
/// 
/// 
public tcomboject GetComObject()
{
返回共对象;
}
公共无效SetComObject(TComObject comObject)
{
CheckAndReleaseComObject();
ComObject=ComObject;
}
公共空间处置()
{
处置(真实);
}
受保护的虚拟void Dispose(bool disposing)
{
如果(处置)
{
//免费管理的资源
}
//免费本地资源(如果有)。
CheckAndReleaseComObject();
}
私有无效检查和释放对象()
{
如果(ComObject!=null)
{
if(ComObject.GetType().IsCOMObject)
Marshal.ReleaseComObject(ComObject);
ComObject=null;
}
}
}

< /代码> 您不能设置此类泛型约束,但是可以考虑使用诸如“代码> MARHALAL.ISCOMBOOST < /COD>”这样的对象来确保对象是COM对象。如果你特别想要一个编译时错误,我认为你运气不好


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

终结器不仅毫无意义,还会使您的程序崩溃。谢谢您,先生!我会更新的code@HansPassant为什么会使程序崩溃?:)谢谢,再次更新了我的代码。在发布之前,我已经使用了ComObject.GetType().IsCOMObject,用于传递模拟作为ComObject的情况(向上投票)