【发布时间】:2014-01-06 15:59:45
【问题描述】:
如果依赖容器或数据访问工厂可以返回可能实现IDisposable的类型,那么客户端是否应该负责检查并处理它?在我下面的代码中,一个数据类实现了IDisposable,而另一个没有。数据访问工厂可以返回任何一个。
private static void TestPolymorphismWithDisposable()
{
// Here we don't know if we're getting a type that implements IDisposable, so
// if we just do this, then we won't be disposing of our instance.
DataAccessFactory.Resolve().Invoke();
// Do we just have to do something like this?
IFoo foo = DataAccessFactory.Resolve();
foo.Invoke();
var fooAsDisposable = foo as IDisposable;
if (fooAsDisposable != null) { fooAsDisposable.Dispose(); }
}
我问的原因是,这似乎给客户端代码带来了负担,必须处理这个问题,以及如何让客户端知道,在构建 API 时,他们可能需要调用处置?在客户端不必检查IDisposable 的情况下,有没有更好的方法来处理这个问题?
为了完整的工作示例,这里是其他类:
public interface IFoo
{
void Invoke();
}
public class DataAccessBaseNotDisposable : IFoo
{
public void Invoke()
{
Console.WriteLine("In Invoke() in DataAccessBaseNotDisposable.");
}
}
public class DataAccessBaseDisposable : IFoo, IDisposable
{
public void Invoke()
{
Console.WriteLine("Invoke() in DataAccessBaseDisposable.");
}
public void Dispose()
{
Console.WriteLine("In Dispose() in DataAccessBaseDisposable.");
}
}
public static class DataAccessFactory
{
public static IFoo Resolve()
{
return new DataAccessBaseDisposable();
//return new DataAccessBaseNotDisposable();
}
}
【问题讨论】:
-
我记得几个月前有一个类似的问题。据我记得你可以做
using(SomeObjectThatMightOrMightNotBeDisposable as IDisposable) { }。这样你就不必明确检查它是否实现了IDisposable。 -
为什么不总是使用 IDisposable?让 IFoo 成为 IDisposable,即使 Dispose 不会为某些实现者做任何需要的事情。
-
@JeroenVannevel 我喜欢这样,但如果类型不是一次性的,当我们尝试调用它的方法时,我们的实例不会是 null 吗?
-
@Ralf 这是一个有趣的想法。这就像空对象模式。我可以有什么都不做的一次性方法,所以所有类型都可以用同样的方式处理。我得考虑一下。谢谢。
-
@BobHorn 这就是 Streams 的工作方式。所有 Streams 都是 IDisposable 的,即使是不需要它的 MemoryStream。
标签: c# polymorphism idisposable