声明类或接口的IDisposable?

Bea*_*ker 45 .net c# dispose idisposable

从以下情况开始:

public interface ISample
{
}

public class SampleA : ISample
{
   // has some (unmanaged) resources that needs to be disposed
}

public class SampleB : ISample
{
   // has no resources that needs to be disposed
}
Run Code Online (Sandbox Code Playgroud)

SampleA类应实现用于释放资源的接口IDisposable.您可以通过两种方式解决此问题:

1.将所需的接口添加到SampleA类:

public class SampleA : ISample, IDisposable
{
   // has some (unmanaged) resources that needs to be disposed
}
Run Code Online (Sandbox Code Playgroud)

2.将其添加到接口ISample并强制派生类来实现它:

public interface ISample : IDisposable
{
}
Run Code Online (Sandbox Code Playgroud)

如果将其放入界面,则强制任何实现实现IDisposable,即使它们没有任何可处置的内容.另一方面,很清楚地看到接口的具体实现需要一个dispose/using块,而你不需要像IDisposable一样进行清理.在两种方式中可能会有更多的优点/缺点...为什么你建议使用一种优先于另一种方式?

Ign*_*cia 22

Inteface分离原则SOLID如果添加了IDisposable你是给方法是不感兴趣的,以便客户端的界面,你应该把它添加到A.

除此之外,界面永远不会丢弃,因为可处置性与界面的具体实现有关,而不是界面本身.

任何接口都可以使用或不使用需要处理的元素来实现.

  • 从理论上讲,您的建议是最正确的,但在实践中,处理具有潜在的一次性实现的接口很麻烦。在很大程度上取决于谁管理对象的生存期。IMO在这里有更好的答案:/sf/answers/1005813581/ (3认同)
  • @nawfal:如果理论与实践不符,则意味着我们使用的工具是错误的,而不是相反。根据定义,接口不能是一次性的,因为您只能处理实现,而不是操作契约。 (2认同)

Fel*_*ano 13

如果将using(){}模式应用于所有接口,最好ISample从中派生,IDisposable因为设计接口时的经验法则是"易于使用"而非"易于实现".

  • "......你只看到界面......"这才是关键.许多优秀的OOP解决方案只使用接口,所以我认为接口实现IDisposable是有意义的.这样消耗代码可以以相同的方式处理所有子类. (2认同)

Jam*_*iec 7

就个人而言,如果所有ISample的都应该是一次性的,我会把它放在界面上,如果只有一些我只会把它放在它应该是的类上.

听起来你有后一种情况.


sup*_*cat 6

如果可能至少有一些实现会实现,则接口IFoo应该IDisposable实现IDisposable,并且至少在某些情况下,对实例的最后存活引用将存储在变量或类型字段中IFoo。几乎可以肯定应该实现IDisposable如有实现可能实现IDisposable和实例将通过工厂接口来创建(如与实例的情况下IEnumerator<T>,在许多情况下是通过工厂接口创建IEnumerable<T>)。

比较IEnumerable<T>IEnumerator<T>很有启发性。某些实现的类型IEnumerable<T>也实现了IDisposable,但是创建此类实例的代码将知道它们是什么,知道它们需要处置,并将其用作其特定类型。这样的实例可以作为类型传递给其他例程IEnumerable<T>,而这些其他例程将不知道最终是否需要处置对象,但是在大多数情况下那些其他例程不是最后一个保留对对象的引用的例程。相比之下,的实例IEnumerator<T>通常是由代码创建,使用并最终被放弃的,而这些代码对实例的底层类型一无所知IEnumerable<T>。一些实现IEnumerable<T>.GetEnumerator()IEnumerator<T>如果IDisposable.Dispose未在放弃方法之前调用它们的方法,则它们的return实现将泄漏资源,并且大多数接受类型参数的代码IEnumerable<T>将无法知道此类类型是否可以传递给资源。尽管有可能IEnumerable<T>包含一个属性EnumeratorTypeNeedsDisposal来指示是否IEnumerator<T>必须处理GetEnumerator()返回的对象,或者仅要求调用例程检查返回的对象的类型以查看其是否实现IDisposable,但无条件调用Dispose方法更快,更轻松。除了确定是否Dispose必要并仅在需要时才调用它,可能没有任何作用。

  • @binki:如果 `GetEnumerator` 返回的实例实现了 `foreach` 的 C# 代码,则调用 `IDisposable`。 (2认同)