自定义类的工作方式类似于带有大括号的using语句

时间:2018-09-26 14:27:38

标签: c# design-patterns

是否可以创建像使用那样工作的类或运算符?

示例:

using (IDataReader reader = cmd.ExecuteReader())
{
  while (reader.Read())
  {
    count++;
  }
}

通常,我们使用using语句不必手动处理发布操作,例如dispose等。

我想到了这种机制的一些用法。
但是我不知道该如何实现。

实际实现的示例:

  MyClass mc = new MyClass();
  MyClass sub = mc.GoDown();
  //Do things on sub
  sub.GoUp();

我想要的是什么

  MyClass mc = new MyClass();
  mc.GoDown {
    //Do things on sub
  } // GoUp

我知道我可以使用try {} finally {}。 我只是好奇是否有办法做using在做什么。

编辑: 我确实了解IDispose的实现。 我只是想知道如果没有using,我们是否可以做using做的事情。

编辑#2: 改进了示例。

3 个答案:

答案 0 :(得分:2)

您的类只需要实现IDisposable来支持在using块中的使用:

public class MyClass : IDisposable
{
    public void Dispose()
    {
        // Do your cleanup
    }
}

然后您可以使用:

using (var instance = new MyClass())
{

}

不过请阅读Microsoft文档上的Implementing a Dispose method

答案 1 :(得分:2)

这是通过向Action<MyClass>传递GoDownGoDown处理GoUp上的sub来使示例工作的方式。

public class MyClass
{
    public MyClass GoDown(Action<MyClass> doStuff)
    {
        var sub = new MyClass();
        //Whatever GoDown did to create a MyClass goes here

        try
        {
            doStuff(sub);
        }
        finally
        {
            sub.GoUp();
        }
    }
}

然后这样称呼它。

MyClass mc = new MyClass();
mc.GoDown(sub =>
{
    //Do things on sub
});

即使您传入的委托中有例外,也会在GoUp上调用sub

答案 2 :(得分:1)

与您建议的最接近的构造是一种将对象和numpyFunc作为参数并且对象是某种类型的方法,例如实现一个接口,然后执行任务。

让我们从一个界面开始:

Action

为简单起见,我为不带任何参数的动作创建了一个示例:

public interface IMyWrapper
{
    void Do();
}

如果您传递实现public class MyWrapper { public static void MyWrapperMethod(IMyWrapper wrapped, Action doStuff) { try { doStuff(); } finally { wrapped.Do(); } } public static void MyWrapperMethod(object notWrapped, Action doStuff) { doStuff(); } } 接口的对象,则在执行IMyWrapper操作中的操作后,它将运行Do()接口的IMyWrapper方法。否则它将只运行doStuff

要像这样调用运行它:

doStuff

这只会写“做事”。

让我们现在创建一个实现界面接口的类:

MyWrapper.MyWrapperMethod(new object(), () =>
{
    Console.WriteLine("Do stuff");
});

并在public class MyWrappedClass : IMyWrapper { public void Do() { Console.WriteLine("I implement the wrapper."); } } 中使用它:

MyWrapperMethod

这将打印“执行任务”和“我实现包装器”。 b / c,var myWrappedClass = new MyWrappedClass(); MyWrapper.MyWrapperMethod(myWrappedClass, () => { Console.WriteLine("Do stuff"); }); 将为我们执行MyWrapperMethod方法。

那是我能想到的最接近Do的地方。