例如我有一个方法
SomeMethod(Graphics g)
{
...
}
如果我以某种方式调用此方法
SomeMethod(new Graphics())
我的图形对象会自动处理还是应该g.Dispose()
在方法结束时手动调用?
SomeMethod(Graphics g)
{
...
g.Dispose();
}
一次性对象不会被自动处理(它们最接近的方法是实现一个Dispose
在必要时调用的终结器)。您必须通过调用Dispose()
或将其与using
块一起使用来手动执行此操作。
如果你想自动处理对象,你可以这样做:
using (var g = new Graphics()) {
SomeMethod(g);
}
using 块确保Dispose()
在块结束后立即自动调用该方法(因此在这种情况下,afterSomeMethod
返回或抛出异常)。
注意:如果可能,您应该将对象放置在您创建它的位置附近。接收一个有效的对象并在方法中处理它可能会导致混淆。
Dispose()
当调用终结器时,图形和可能大多数(如果不是全部)实现此接口的 BCL 类也将调用。这是正确实施的一部分IDisposable
。但是,您永远不知道何时调用终结器,如果您需要确定性地处理您的对象,则不应依赖此实现细节。
使用一次性物品的正确方法是将它们包装在using
块中:
using (var g = new Graphics()) {
SomeMethod(g);
}
当执行离开using
块时,Graphics
即使抛出异常,也会正确处理。
但是,如果您不使用using
块显式或隐式处理对象,则在垃圾收集时对象仍将被处理(假设终结器正确调用了Dispose
它应该的)。当这种情况发生时不在您的控制范围内,这就是为什么您应该确保在不再需要一次性对象以释放对象占用的资源时立即正确处置它们。
您可能应该使用 using 语句
using (var graphicsObject = new Graphics()) {
SomeMethod(graphicsObject);
}
即使发生异常,该对象也会在 using 语句的末尾自动释放。
检查图形类
public sealed class Graphics : MarshalByRefObject,
IDeviceContext, IDisposable
它实现了IDisposable
接口,因此如果您将using
语句与 Graphics 对象一起使用,那么它将自动释放。
在你的例子中
SomeMethod(Graphics g)
{
...
g.Dispose();
}
它将使用g.Dispose
, 但最佳做法是using
声明。
例子:
using (Graphics g = this.CreateGraphics())
{
//Do some graphics operation.
}
在您的示例中,您不应该处理作为参数提供给您的对象。这是不可取的,因为该对象可以在您的方法之外使用。实用程序对象的处置应该(通常)以您创建它的相同方法进行。类范围对象或状态对象的例外。
与其他答案一样,用于using
创建和处置对象。这仅在使用一些有价值的资源(如数据库连接)的对象上才是真正需要的。话虽如此,如果对象实现它,您应该始终调用Dispose()
(显式或通过using
),因为这意味着它使用非托管或大量资源。
您不调用Dispose
(无论哪种方式)的所有 .NET Framework 对象最终都将由垃圾收集器自动处理。接口的正确实现IDisposable
应该具有调用Dispose
. 这是为了确保有价值的资源不会因为糟糕的代码而丢失。你的资源会在很久以后才被释放,但它们会,这很重要。这就是 .NET 中所有一次性类的实现方式以及所有类应该如何实现的方式IDisposable
。
您的代码应如下所示:
using(Graphics g = new Graphics())
{
SomeMethod(g)
{
...
}
}
检查此Microsoft 对IDisposable.Dispose
方法的建议。