2010-09-27 43 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