首页 文章

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

提问于
浏览
3

我喜欢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中实际处理任何内容,因此它是空的 .

My question is, is there any drawback to using IDisposable in this way?

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

EDIT:

好吧,所以我想我有点特定,但是's a wider point here. The using statement is a handy, very neat way to define an instance for a specific length of time, and then you can forget about it. Its seems unfair that this ability should be restricted to IDisposable objects only. Yes there'不仅仅是实例化然后设置为null,还有一定程度的懒惰,但是使用块使得它非常具体,实例的范围是什么 . Why shouldn't I be allowed to do it with non IDisposable classes?

6 回答

  • 2

    当您实现 IDisposable 时,您还需要实现 IDisposable 以便处置您的实例 . 这对您 class 的用户产生了一种人为的要求 .

    您可以使用范围来实现您想要的效果:

    {
      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 语句来达到你想要的目的 . 您可以使用lambdas来实现这一点,就像我使用 With 扩展方法显示的那样 . 事实上,这就是在_1360686中完成了一些并行"constructs" .

  • 0

    如果你的 class 没有't need to be disposed, there'使用 using 没有意义 .

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

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

    但是,我没有看到目的 .

    从设计角度来看,您不应该不必要地实现 IDisposable .
    实现 IDisposable 告诉使用您的类的人它使用昂贵的资源,并且在完成时必须处理 .
    如果那个's not actually true, you'只是让他们的工作更难 .

  • 5

    是的,using块是try / finally块的语法糖 .

  • 1

    我不会(ab)使用 using 来限制方法中的变量范围,除非这些类型确实需要处理 - 它可能只会让人感到困惑 . 对于您的示例,听起来更像是您希望添加一个额外的方法来更好地构建代码(并且可能获得相同的可读性优势):

    public void WorkWithMyInstance(MyInstance t)
    {
      t.Foo= "Hello";
      t.Bar= "World";
      ...
    }
    
  • 5

    你并没有真正按照预期使用界面 . 按documentation

    此接口的主要用途是释放非托管资源 .

    如果您只是使用 IDisposable ,那么您可以将其包装在 using 语句中,我认为这会给您的类用户留下错误的印象 . 他们可能会将此代码解释为比它实际做的更多 .

    我认为意想不到的后果将是混乱 .

  • 0

    你也可以使用这个吗?

    var myclass = new MyClass
    {
    MyProperty1 = "Property1",
    MyProperty2 = "Property2",
    };
    

相关问题