2012-11-01 37 views
0

我有一個通用的基類包裝COM對象,並希望將其約束到COM對象。 我試過where TComObject : IUnknown但編譯器不喜歡它。有沒有辦法做到這一點?通用約束的COM對象

我使用下面的代碼,請給出反饋,如果你發現一些愚蠢的東西。

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; 
     } 
    } 
} 
+0

終結者不僅沒有意義,而且會導致程序崩潰。 –

+0

謝謝先生!我將更新代碼 –

+0

@HansPassant爲什麼它會使程序崩潰? :) –

回答

1

不能設定通用的限制,你可以,但是,可以考慮使用像Marshal.IsComObject的東西,以確保該對象是一個COM對象。如果你特別想要一個編譯時錯誤,我認爲你運氣不好。

此外,請注意SetComObject可以被多次調用,在這種情況下,您不會「清除」可能已經設置的任何com對象。此外,您現在可以刪除GC.SuppressFinalize,因爲您已經移除了終結器/析構函數,而這確實不是必需的,因爲如果框架將進入垃圾回收,框架將爲您釋放com對象。

+0

謝謝你,再次更新我的代碼。我已經使用ComObject.GetType()。IsCOMObject之前發佈的情況下,當我通過一個模擬ComObject(上投票) –