出于可读性原因,使用空Dispose实现IDisposable

我喜欢using(){}语句来控制范围和可读性。 您不仅可以创建对象,使用它们并整齐地处理它们,而且还可以像这样使用它:

假设myInstance是来自代码中其他地方MyClass的一个实例 - 也就是方法参数或其他东西

using (var t = myInstance) {
    t.Foo= "Hello";
    t.Bar= "World";
    ...
}

MyClass的定义:

public class MyClass : IDisposable
{
   public string Foo {get; set;}
   public string Bar {get; set;}
   ...

   public void Dispose() {}
}

这使得代码更加整洁,更具可读性(我感觉),并且更容易打字。 然而,为了广泛使用这个,你必须实现IDisposable。 在这种情况下,不需要MyClass实际处理Dispose中的任何内容,因此它是空的。

我的问题是,以这种方式使用IDisposable有什么缺点吗?

我很欣赏这个问题已经存在类似的问题,但我不认为这些问题涉及到为此目的使用IDispose(或者它们涉及特定的类)。

编辑:

好的,所以我想我是有点特殊的,但这里有一个更广泛的观点。 使用语句是一种方便,非常简洁的方式来定义特定时间的实例,然后您可以将其忽略。 它似乎不公平,这种能力应该只限于IDisposable对象。 是的,在实例化过程中有一定程度的懒惰,然后设置为null,但是使用块使得它非常具体地描述了实例的范围。 为什么我不应该被允许使用非IDisposable类来做到这一点?


当您实施IDisposable您宣传您的班级是特殊的,需要妥善处理。 不仅使用这样的内联代码,而且当类持有对你的类的引用时。 他们还需要实现IDisposable才能处理您的实例。 这会对您班级的用户造成人为的要求。

你可以使用一个范围来实现你想要的:

{
  var _ = instance;
  _.Foo = "Hello"; 
  _.Bar = "World"; 
}

另一个选择是这样的:

instance.With(_ => {
  _.Foo = "Hello";
  _.Bar = "World"; 
});

...

public static class WithExtensions {
  public static void With<T>(this T instance, Action<T> action) {
    action(instance);
  }
}

这个更好,因为发生的更明确。

我也看到了你的痛苦。 如果我们可以定义我们自己的控制块(比如在Nemerle中),会更好。 尽管C#不允许这种定制,但您不应该滥用特定的using语句来实现您想要的功能。 你可以使用lambda来做到这一点,这很像我用With扩展方法展示的方式。 事实上,这就是任务并行库中的一些并行“构造”。


如果你的班级不需要处理,那么使用using就没有意义。

相反,你可以做一个正常的块:

{ var t = myInstance;
    t.Foo= "Hello";
    t.Bar= "World";
    ...
}

但是,我看不到目的。

从设计的角度来看,您不应该不必要地实现IDisposable
实现IDisposable告诉使用您的课程的人使用昂贵的资源,并且必须在完成时处置。
如果那不是真的,那么你只是在努力工作。


是的,使用块是try / finally块的语法糖。

链接地址: http://www.djcxy.com/p/54457.html

上一篇: Implementing IDisposable with empty Dispose for reasons of readability

下一篇: Should you implement IDisposable.Dispose() so that it never throws?