Pet*_*ing 15 c# dispose idisposable
如何确定是否应该使用IDisposable扩展我的一个接口或在实现我的接口的类上实现IDisposable?
我有一个不需要处理任何外部资源的接口,除了一个特定的实现.我的选择似乎是:
1)在接口上实现IDisposable,要求所有实现都实现Dispose,即使只是一个空方法.
-要么-
2)仅在需要处理资源的类上实现IDisposable.这将导致"使用"问题,因为我的对象是从工厂创建的,因此所有上游代码都对接口起作用.由于接口未绑定到IDisposable,因此"使用"不会看到Dispose方法.但是,我可以将工厂结果转换为实施; 然而,这会使消费者意识到实施,从而破坏了接口的目的.
关于最佳实践的任何想法?
Ser*_*rvy 15
如果您希望调用者只能与接口交互,而不是实现,那么您希望扩展接口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();
}
Run Code Online (Sandbox Code Playgroud)
如果foo不执行的话IDisposable,也就using相当于using(null)可以正常工作了。
以下示例程序的输出将是
Fizz.Bar
Fizz.Dispose
Buzz.Bar
Run Code Online (Sandbox Code Playgroud)
示例程序
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();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2638 次 |
| 最近记录: |