将"使用"用于资源处理以外的事物

Cem*_*for 8 c# using-statement

我们都知道该using语句非常适合您想要及时清理的资源,例如打开文件或数据库连接.

我想知道在资源清理不是Dispose()方法的目标而是重置为先前状态的情况下使用该语句是否是一件好事.

例如,一个允许using语句包装过程的类,该过程需要花费大量时间并将Cursor更改为等待状态.

class CursorHelper : IDisposable
{
   readonly Cursor _previousState;
   public CursorHelper(Cursor newState)
   {
      _previousState = Cursor.Current;
      Cursor.Current = newState;
   }

   public void Dispose()
   {
      Cursor.Current = _previousState;
   }
}
Run Code Online (Sandbox Code Playgroud)

然后可以这样使用类,而不必担心在完成后还原Cursor.

public void TimeIntensiveMethod()
{
   using (CursorHelper ch = new CursorHelper(Cursors.WaitCursor))
   {
      // something that takes a long time to complete
   }
}
Run Code Online (Sandbox Code Playgroud)

这是否适用于该using声明?

Jas*_*son 5

实际上using简单来说就是语法糖try/finally,所以为什么你不要像以下那样只做简单的尝试/终极...

try
{
    // do some work
}
finally
{
    // reset to some previous state
}
Run Code Online (Sandbox Code Playgroud)

imho实现Dispose方法重置为某种状态会产生误导,特别是如果你的代码有消费者.


Joe*_*Joe 5

(ab)using以这种方式使用语句肯定有先例,例如ASP.NET MVC框架中的FormExtensions.BeginForm.这会在处理<form>时呈现结束标记,其主要目的是在MVC视图中启用更简洁的语法.Dispose即使抛出异常,该方法也会尝试呈现结束标记,这有点奇怪:如果在呈现表单时抛出异常,您可能不希望尝试呈现结束标记.

另一个例子是log4net框架中的(现已弃用的)NDC.Push方法,该方法返回IDisposable其目的是弹出上下文.

一些纯粹主义者会说这是一种虐待,我建议你根据具体情况自行判断.就个人而言,我没有看到你的渲染沙漏光标的例子有什么问题.

@ I4V评论中讨论有一些有趣的意见 - 包括反对无处不在的Jon Skeet的这种"滥用"的论点.