如何处理类而不是封装一次性实例?

发布于 2024-10-09 11:23:08 字数 651 浏览 5 评论 0原文

interface IMyInterace
{
void Open();
object Read();
void Close();
}

class MyImplementation : IMyInterface
{
public void Open() { /* instantiates disposible class */ }
//...
public void Close() { /* calls .Dispose(); */ }

}

有没有一个好的方法来处理这种情况,以确保调用类内的一次性实例? (除了文档之外,没有任何信号告诉调用者必须调用“Close”。)IMyInterface 的实现不一定封装 IDisposible 实例,并且在应用程序的整个生命周期中重复关闭和重新打开。

我正在考虑这样做:

  • 在 MyImplementation 中实现 IDisposible。
  • 设置 Dispose() 来调用 Close()。
  • 添加对 Close() 或 Dispose() 的调用 开放开始以确保先前 通话已关闭。

IMyInterface 的用户不知道他们正在使用什么实现,因此我不确定使 MyImplementation 成为一次性的有多大价值,而且并非所有实现都会封装 IDisposibles。

interface IMyInterace
{
void Open();
object Read();
void Close();
}

class MyImplementation : IMyInterface
{
public void Open() { /* instantiates disposible class */ }
//...
public void Close() { /* calls .Dispose(); */ }

}

Is there a good way to deal with this type of situation to ensure that disposible instances inside the class get called? (There is no signal to callers that they must call 'Close' except in documentation.) Implementations of IMyInterface do not necessarily encapsulate IDisposible instances and are closed and reopened repeatedly throughout the application's lifetime.

I'm thinking of doing this:

  • Implement IDisposible in MyImplementation.
  • Set Dispose() to call Close().
  • Add a call to Close() or Dispose() to the
    begining of Open to ensure previous
    call was closed.

Users of IMyInterface do not know what implementation they are using, so I'm not sure how much value making MyImplementation disposible has, and again, not all implementations will encapsulate IDisposibles.

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

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

发布评论

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

评论(3

小女人ら 2024-10-16 11:23:08

处理此问题的标准方法是简单地让 MyImplementation 实现 IDisposable

The standard way to handle this is to simply have MyImplementation implement IDisposable.

幸福%小乖 2024-10-16 11:23:08

正如约翰提到的,你的第一个要点是正确的。

有时,Close() 方法在功能上与 Dispose() 是同义的,并且存在是为了保持与抽象的语义一致性。也就是说,补充 Open() 方法。其他时候,Close() 将允许您重新打开,但 Dispose() 则不允许。因此,你的第二个要点也很好。

要点 3 不一定适用,因为废弃的对象不应重复使用。如果需要再次调用Open(),则需要使用新的实例。事实上,一旦调用了 Dispose()(通过检查私有 dispose< /code> 布尔标志)。如果您希望对象支持关闭后重新打开,您可以考虑使用 Debug.Assert() 和/或在调用 Open() 时不带 <代码>关闭()。这将有助于防止对这些实例的草率管理。

请务必遵循完整的一次性模式,这比简单地实现接口更复杂:

bool disposed;

public void Dispose() // don't make virtual!
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    if(!disposed)
    {
        if(disposing) 
        {
            // dispose of managed resources here, for example:
            // if(resource != null) { resource.Dispose(); } 
        }
    }

    // dispose of unmanaged resources here 

    disposed = true;
}

As John mentioned, your first bullet point is right on.

Sometimes a Close() method is functionally synonymous with Dispose(), and exists to maintain semantic consistency with an abstraction. That is, to complement a Open() method. Other times, Close() will allow you to re-open, but Dispose() should not. Your second bullet-point is therefore fine, as well.

Bullet point 3 is not necessarily applicable, because a disposed object should not be reused. If you need to call Open() again, you need to use a new instance. In fact, the Open() method should throw an ObjectDisposedException once Dispose() have been called (by checking a private disposed boolean flag). If you want the object to support re-opening after close, you might consider using Debug.Assert() and/or throwing an exception if Open() is called without Close(). This will help to prevent sloppy management of these instances.

Be sure to follow the full disposable pattern, which is more involved than simply implementing the interface:

bool disposed;

public void Dispose() // don't make virtual!
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    if(!disposed)
    {
        if(disposing) 
        {
            // dispose of managed resources here, for example:
            // if(resource != null) { resource.Dispose(); } 
        }
    }

    // dispose of unmanaged resources here 

    disposed = true;
}
缪败 2024-10-16 11:23:08

除了这里已经有了的答案:

如果这个类(经常/有时)单独通过接口使用,我建议从 IDisposable 继承 IMyInterace。

这将使您的用户以一致的方式使用这些对象。当然,缺点是您可能需要向实际上不需要它的类添加(虚拟)Dispose 方法。但好处在于一致性和灵活性:如果将来某个类发生变化而需要 Dispose() 该怎么办?

一个最小的方法:

interface IMyInterace : IDisposable { }

sealed class MyImplementation : IMyInterface 
{   
   public void Open() { /* instantiates disposible class */ }

   public void Close() { /* calls _myField.Dispose(); */ }

   public void Dispose() { Close(); }  // only use this short form in a sealed class

}

In addition to the answers already here:

If this class is (often/sometimes) used through the interface alone I would advice to inherit IMyInterace from IDisposable.

That will let your users use these objects in a consistent manner. The drawback is of course that you may need to add (dummy) Dispose methods to classes that don't actually need it. But the benefit is in consistency and flexibility: What if a class changes in the future so that it does need a Dispose() ?

A minimal approach:

interface IMyInterace : IDisposable { }

sealed class MyImplementation : IMyInterface 
{   
   public void Open() { /* instantiates disposible class */ }

   public void Close() { /* calls _myField.Dispose(); */ }

   public void Dispose() { Close(); }  // only use this short form in a sealed class

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