2010-09-27 59 views
0

我有一個C#.NET 2.0 CF項目,我使用了許多本地方法。其中有幾種方法圍繞着某種類型的對象HANDLE。我想抽象出使用泛型這樣把手管理的生命週期:用泛型管理本地句柄

public abstract class IHandleTraits 
{ 
    public abstract IntPtr Create(); 
    public abstract void Release(IntPtr handle); 
} 

public sealed class SafeHandle<T> : IDisposable where T : IHandleTraits 
{ 
    private bool disposed; 
    private IntPtr handle_ = NativeMethods.INVALID_HANDLE_VALUE; 
    public SafeHandle() 
    { 
     // error CS0119: 'T' is a 'type parameter', which is not valid in the given context 
     handle_ = T.Create(); 
     if (NativeMethods.INVALID_HANDLE_VALUE == handle_) 
     { 
      // throw win32 exceptions 
     } 
    } 

    ~SafeHandle() 
    { 
     this.Dispose(false); 
    } 

    public IntPtr Handle 
    { 
     get { return handle_; } 
    } 

    public void Dispose(bool disposing) 
    { 
     if (this.disposed) 
     { 
      // error CS0119: 'T' is a 'type parameter', which is not valid in the given context 
      T.Release(handle_); 
      handle_ = NativeMethods.INVALID_HANDLE_VALUE; 
     } 
     this.disposed = true; 
    } 

    public void Dispose() 
    { 
     this.Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
} 

現在,我可以定義一個特徵結構,每個手柄式是這樣的:

internal sealed class MyHandleTraits : IHandleTraits 
{ 
    // error CS0112: A static member cannot be marked as override, virtual, or abstract 
    public static override IntPtr Create() 
    { 
     return NativeMethods.CreateHandle(); 
    } 

    // error CS0112: A static member cannot be marked as override, virtual, or abstract 
    public static override void Release(IntPtr handle) 
    { 
     NativeMethods.ReleaseHandle(handle); 
    } 
} 

而且在使用它應用程序是這樣的:

using (SafeHandle<MyHandleTraits> MyHandle = new SafeHandle<MyHandleTraits>) 
{ 
    // execute native methods with this handle 
} 

顯然,這有幾個問題:

  1. 如何爲static函數定義abstract接口?
  2. 當我嘗試使用泛型,我得到一個錯誤,說它是一個「類型參數」,它是「在給定的上下文中無效」。

我能做些什麼來解決或解決這些問題?

感謝, PaulH

回答

1

是的,不能工作。您需要實現IHandleTraits的類的實際實例。接口需要一個實現v表的類。只要你想密封這個類,你需要一個工廠或創建一個T的實例。

實際上,對象層次結構是錯誤的。 SafeHandle應該是一個具有派生類的抽象基類,每個類都知道如何處理特定的句柄類型。這也是SafeHandle桌面版本的實現方式。

您可以通過給T new()約束來拯救您的方法,以便您可以創建它的一個實例。拖動額外的引用並不是那麼好:

public sealed class SafeHandle<T> : IDisposable where T : IHandleTraits, new() { 
    private bool disposed; 
    private IntPtr handle_ = IntPtr.Zero; 
    private T handleType; 
    public SafeHandle() { 
     handleType = new T();       
     handle_ = handleType.Create(); 
    } 
    // etc... 
} 
+0

我按照您的建議重新安排了對象層次結構。再次感謝。 – PaulH 2010-09-27 20:45:38