在每个函数中使用语句 -> 通过适当的清理转换为类字段?

问题描述 投票:0回答:6

基本上我有一些如下所示的函数:

class MyClass
{
    void foo()
    {
       using (SomeHelper helper = CreateHelper())
       {
           // Do some stuff with the helper
       }
    }

    void bar()
    {
        using (SomeHelper helper = CreateHelper())
        {
           // Do some stuff with the helper
        }
    }
}

假设我可以在每个函数中使用相同的资源而不是不同的资源[实例],那么在清理等方面这样做可以吗?:

class MyClass
{
    SomeHelper helper = CreateHelper();

    // ...foo and bar that now just use the class helper....

    ~MyClass()
    {
      helper.Dispose();
    }
}
c# .net idisposable
6个回答
8
投票

不,不要添加析构函数(终结器)。

您可以重用资源,但您的类必须实现

IDisposable

sealed class MyClass : IDisposable { SomeHelper helper = CreateHelper(); // ...foo and bar that now just use the class helper.... //~MyClass() public void Dispose() { helper.Dispose(); } }

现在您必须在 using 块中使用

MyClass

 实例。它本身已成为
托管资源

析构函数是没有用的,每当收集 MyClass 实例时,关联的辅助对象也将位于同一个集合中。但拥有析构函数仍然会产生相当大的开销。

IDisposable 的

标准模式使用virtual void Dispose(bool disposing)

方法,但是在创建类
sealed
时,您可以使用上面的简约实现。 


2
投票
在.NET中

你根本不知道何时(或是否)调用终结器

相反,

明确表明您的班级将通过实现IDisposable

被处置
(这正是
SomeHelper
所做的)

class MyClass : IDisposable { readonly SomeHelper helper = CreateHelper(); // any method can use helper public void Dispose() { helper.Dispose(); } } using(var myObj = new MyClass()) { // at the end, myObj.Dispose() will trigger helper.Dispose() }

我使用

readonly

 来确保 
helper
 不会被重新分配到班级中的其他地方,但如果你小心的话,这真的并不重要。

您必须格外小心,切勿将其设置为

null

,否则您的 
Dispose
 将引发异常。如果该字段为 
protected
,您可以在调用 
Dispose
 之前检查是否为空,这样您就知道自己是安全的。


1
投票
您可以在对象的生命周期内共享此类资源,在这种情况下,建议您

实现 IDisposable


1
投票
不,不是。你不知道什么时候最终确定。此外,如果您的资源受到管理,它将在某个时候被处置,而不会最终确定。

如果你不想一直使用using,也许你可以在很多函数中使用一次。


1
投票
约定是,如果你的类拥有一个

IDisposable

 对象,它也应该实现 
IDisposable
。因此,您的类不应该实现终结器,而应该实现 
IDisposable
 并在那里处理助手。

实现终结器的一个问题是您无法控制它何时被调用。一次性模式为您提供了一种更加确定的清理资源的方式。


1
投票
您不需要重写对象中的终结器,您已在第二个代码示例中通过

~MyClass()

 显示了该终结器。

您将需要实施

IDisposable

 模式。如果您使用的是托管资源和非托管资源,您的问题并没有明确说明,但这里有一个托管资源的快速示例。 Stackoverflow 有无数这方面的例子。 Reed Copsey 也有一个很好的系列,您可以从
这里开始

class MyClass : IDisposable { private bool _Disposed; private SomeHelper _Helper; protected virtual void Dispose() { this.Dispose(true); } public void Dispose(bool disposing) { if (_!Disposed && disposing) { if (_Helper != null) _Helper.Dispose(); _Disposed = true; } } }
    
© www.soinside.com 2019 - 2024. All rights reserved.