出于可读性原因,使用空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?