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

发布于 2024-12-17 14:51:47 字数 626 浏览 2 评论 0 原文

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

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();
    }
}

Basically I have a few functions that look like this:

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
        }
    }
}

Under the assumption I can use the same resource instead of a different one [instance] in every function is it ok practice in regard to cleanup and such to do this?:

class MyClass
{
    SomeHelper helper = CreateHelper();

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

    ~MyClass()
    {
      helper.Dispose();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

请持续率性 2024-12-24 14:51:47

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

您可以重用该资源,但您的类必须实现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 disposeing) 方法,但在使类sealed 时,您可以使用上面的简约实现。

No, do not add a destructor (Finalizer).

You can reuse the resource but then your class has to implement IDisposable.

sealed class MyClass : IDisposable
{
    SomeHelper helper = CreateHelper();

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

    //~MyClass()
    public void Dispose()    
    {
      helper.Dispose();
    }                         
}

And now you have to use MyClass instances in a using block. It self has become a managed resource .

A destructor is of no use, whenever a MyClass instance is being collected the associated helper object will also be in the same collection. But having a destructor still incurs considerable overhead.

The standard pattern for IDisposable uses a virtual void Dispose(bool disposing) method but when making the class sealed you can use the minimalistic implementation above.

波浪屿的海角声 2024-12-24 14:51:47

在.NET 你不知道终结器何时(或是否)根本没有调用

相反,明确表明您的类将被 ="nofollow">实现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 将引发异常。如果该字段受保护,您可以在对其调用Dispose 之前检查是否为空,这样您就知道自己是安全的。

In .NET you don't know when (or whether) finalizer is called at all.

Instead, explicitly indicate that your class is to be disposed of by implementing IDisposable:
(This is exactly what SomeHelper does)

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()
}

I used readonly to ensure helper doesn't get re-assigned somewhere else in the class, but this really doesn't matter if you're careful.

You must be extra careful to never set it to null, or your Dispose will throw an exception. If the field is protected, you can check for nullity before calling Dispose on it so you know you're playing safe.

仅此而已 2024-12-24 14:51:47

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

You can share such a resource during the lifetime of your object, in which case it is recommended that you implement IDisposable.

固执像三岁 2024-12-24 14:51:47

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

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

No, it is not. You don't know when the finalized will un. Also, if your resource is managed, it will be disposed of at some point without the finalized.

If you don't want to use using all the time, perhaps ou can use it once around many functions.

草莓味的萝莉 2024-12-24 14:51:47

约定是,如果您的类拥有一个 IDisposable 对象,它也应该实现 IDisposable。因此,您的类不应该实现终结器,而应该实现 IDisposable 并在那里处理助手。

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

The convention is that if your class owns an IDisposable object it should also implement IDisposable. So rather than implementing a finalizer your class should implement IDisposable and dipose of the helper there.

One problem with implementing the finalizer is that you have no control over when it's being called. The disposable pattern gives you a more deterministic way of cleaning up resources.

︶ ̄淡然 2024-12-24 14:51:47

您不需要重写对象中的终结器,您已在第二个代码示例中通过 ~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;
     }
   }
}

You don't need to override the finalizer in your object, which you have shown in your second code sample by ~MyClass().

You will need to implement the IDisposable pattern. You haven't been explicit in your question if you are using managed and unmanaged resources, but here's a quick sample for a managed resource. Stackoverflow has a myriad of examples on this. Reed Copsey also has a good series on it, and you can start here.

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;
     }
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文