我怎么能确定我是否应该在实现我的接口的类的扩展接口,我用一个或的IDisposable实现IDisposable?
我并不需要处置的任何外部资源,除了一个特定实现的接口。 我的选择似乎是:
1)要求所有的实施方式的实现Dispose,即使只有一个空方法的界面上实现IDisposable。
-要么-
2)上只有具有资源需要被设置的类实现IDisposable。 这将导致与“使用”,因为我的目标是从工厂创建,因此所有上游代码工作针对接口问题。 由于接口未绑定到IDisposable的,“使用”不看Dispose方法。 不过,我可以投出厂结果的执行情况; 然而,然后让消费者知道的实施,击败接口的目的。
任何想法,以最佳做法?
如果您希望来电者只能够与之交互的界面,并且从来没有实施,那么你想拥有的接口扩展IDisposable
。 如果不是这样,他们就需要检查value is IDisposable
无论如何,看它是否需要处置。
如果负责的对象处置的对象知道具体实施的,它是永远只被给予了对它的引用(但不负责其处置)使用该接口的对象,再考虑第二个选项。
第一个选项的一个很好的例子是IEnumerator
。 许多IEnumerator
对象不需要时,他们倾向于做任何事情,但有些做的,所以接口扩展IDisposable
,因为负责创建对象/该对象的生命周期将(或应该)从来没有底层实现的知识。
第二的一个例子是类似IComparer
需要进行比较是一次性的许多对象,但使用对象通过该接口的代码段是不负责的创作/生命周期,所以它需要毫不知情与否该类型是一次性的。
$ 50,000问题是,是否处置的责任将永远不会随着接口或通过后,换一种说法,最后实体是否使用一个执行对象可能是比创建它的实体以外的东西。
大原因IEnumerator<T>
实现IDisposable
是,实施的目的是通过实现对象创建IEnumerable<T>.GetEnumerator()
但随后通常使用的其他对象。 实现该对象IEnumerable<T>
就知道它返回真东西是否需要处置,但不会有任何的对象还是用它做得知。 调用代码IEnumerable<T>.GetEnumerator()
会知道什么时候它与返回的对象来完成,但无法知道它是否需要任何清理的方式。 的明智的做法是指定它调用代码IEnumerable<T>.GetEnumerator()
是必需的,以确保返回的对象将具有Dispose
它称之为被放弃前; 该Dispose
方法在许多情况下不能做任何事情,但无条件地调用它是保证存在比检查不存在的方法的存在更便宜的一个什么都不做的方法。
如果您的接口类型的性质是这样的一个执行对象是否需要清理和当这样的清理应该发生的都将是由同一实体交代的问题,那么就没有必要继承接口IDisposable
。 如果情况将由一个实体来创建,但最后被另一个使用,则继承IDisposable
将是明智的。
如果实现IDisposable
在具体的类和接口的用户都知道,这可能是一次性的; 你可以做
IFoo foo = Factory.Create("type");
using(foo as IDisposable){
foo.bar();
}
如果foo
没有实现IDisposable
,在using
将达到using(null)
这会工作得很好。
以下示例程序的输出将是
Fizz.Bar
Fizz.Dispose
Buzz.Bar
示例程序
using System;
internal interface IFoo
{
void Bar();
}
internal class Fizz : IFoo, IDisposable
{
public void Dispose()
{
Console.WriteLine("Fizz.Dispose");
}
public void Bar()
{
Console.WriteLine("Fizz.Bar");
}
}
internal class Buzz : IFoo
{
public void Bar()
{
Console.WriteLine("Buzz.Bar");
}
}
internal static class Factory
{
public static IFoo Create(string type)
{
switch (type)
{
case "fizz":
return new Fizz();
case "buzz":
return new Buzz();
}
return null;
}
}
public class Program
{
public static void Main(string[] args)
{
IFoo fizz = Factory.Create("fizz");
IFoo buzz = Factory.Create("buzz");
using (fizz as IDisposable)
{
fizz.Bar();
}
using (buzz as IDisposable)
{
buzz.Bar();
}
Console.ReadLine();
}
}
文章来源: Determining if IDisposable should extend an interface or be implemented on a class implementing said interface