是否必须处理本机方法引用 - 如果有的话,有任何建议的做法

时间:2010-10-04 11:58:42

标签: .net unmanaged idisposable

我有一个使用user32.dll中的方法的类:

[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr windowHandlerPtr);

根据Effective C#,所有使用非托管代码的类都应该同时实现IDisposable和终结器。没有深入讨论的细节,是否需要处理这种外部方法声明?如果是这样 - 那个dispose方法怎么样?

3 个答案:

答案 0 :(得分:3)

这不是真正的“参考”,而是宣言。它实际上并没有创造任何东西,所以不需要处理(实际上没有任何东西可以处理)。

从非托管代码中使用返回值是你应该注意的事情 - 在这种情况下,它只是一个你不需要担心的bool。但在大多数情况下,您应该查看非托管API的文档,看看它是否应该以某种方式发布。如果是,则将其包装在可以正确处理的类中。这是一个decent article on IDisposable

经验法则是:如果它实现IDisposable总是处理它,并且如果它是非托管资源,请确保它已正确释放。

答案 1 :(得分:1)

在这种情况下,IntPtr没有要处理的非托管资源。返回值为bool也是如此,以同样的方式无关。但是,如果你掌握IntPtr,你可能很重要,如果你创建它(例如createDC),你需要释放它(通过调用另一个非托管方法)但在这种情况下你只需要获取值然后传递它

答案 2 :(得分:1)

  

根据Effective C#,所有使用非托管代码的类都应该实现IDisposable和终结器。

不,这是关于使用非托管资源,而不是代码。在Windows中,资源几乎总是由“句柄”表示。非托管代码本身不是资源,除了DLL的句柄之外没有与之关联的内核对象,这是您无权访问的句柄。

传递给SetForegroundWindow的参数确实是其中一个资源。它是一个窗口的句柄。但是您没有自己创建该窗口,而是尝试将焦点设置为已创建并由其他代码管理的窗口。您应该处置您未创建的对象。

值得注意的是,建议已经过时。 Windows句柄应该由一个SafeHandle派生类包装。他们已经提供了终结器,你不应该实现自己的终结器。只需实现Dispose()并调用SafeHandle.Dispose()方法。