不好的做法?非正式使用c#的using语句

sna*_*arf 19 c# using-statement

C#具有该using语句,特别是对于IDisposable对象.据推测,using语句中指定的任何对象都将拥有某种应该确定性释放的资源.

然而,在我看来,编程中有许多设计具有单一,明确的开始和结束,但缺乏内在的语言支持.该using构造提供了使用代码编辑器的内置特征的机会,至少清楚且自然地突出了这种设计或操作的范围.

我想到的是经常以a BeginXXX()EndXXX()方法开始的那种操作,尽管有很多不同的风格,例如涉及"开始"和"连接"的异步代码执行.

拿这个天真的例子吧.

webDataOperation.Start();
GetContentFromHardDrive();
webDataOperation.Join();
// Perform operation that requires data from both sources
Run Code Online (Sandbox Code Playgroud)

相反,如果Start方法返回了一个IDisposable.Dispose方法执行连接操作的对象,该怎么办?

using(webDataOperation.Start()) {
    GetContentFromHardDrive();
}
// Perform operation that requires data from both sources
Run Code Online (Sandbox Code Playgroud)

或者,更好的是,我特别想到的是:我有一个对象,它具有高度专业化的图形blitting,并且有一个Begin()End()方法(一个设计也出现在DirectX和XNA中).代替...

using(blitter.BlitOperation()) {
    // Do work
}
// Use result
Run Code Online (Sandbox Code Playgroud)

它似乎更自然,更易读,但它是不可取的,因为它使用IDisposable界面和using声明用于非预期的目的?换句话说,这是否与以非直观的方式运算符操作符相同

Ree*_*sey 20

这是一种完全可以接受的做法.这些被称为因子类型,框架设计指南建议这样做.

基本上,如果类型包装具有特定生命周期的操作,则使用IDisposable和using语句将成为适当的考虑因素.

我实际上也在这里写了关于这个特定主题的博客.


Eri*_*ert 12

我建议不要这样做; 我的信念是代码是与代码的维护者有效地沟通,而不是编译器,并且应该记住维护者的理解.我尝试仅使用"使用"来处置资源,通常是非托管资源.

我是少数.大多数人似乎使用"使用"作为一般目的"我想要一些清理代码运行,即使抛出异常"机制.

我不喜欢这个,因为(1)我们已经有了一种机制,称为"try-finally",(2)它使用了一个功能,它不是用于它的目的,以及(3)如果调用清理代码是重要的是,为什么它在被调用时不可见?如果它很重要,那么我希望能够看到它.


Rya*_*rle 6

只因为你可以(或因为Phil Haack说它没关系),并不意味着你应该这样做.

基本的经验法则:如果我能阅读你的代码并了解它的作用以及你的意图,那么它是可以接受的.另一方面,如果你需要解释你做了什么,或者为什么要这样做,那么可能会让负责维护代码的初级开发人员绊倒.

还有许多其他模式可以通过更好的封装来实现这一目标.

底线:这种"技术"不会给你带来什么,只会让其他开发者感到困惑.

  • @Snarfblam:在某些情况下,使用一个接受委托的方法(某种形式的某个Action/Func),并在你的启动/拆解代码之间调用它.但是,有些案例没有通过这种方法处理.有关详细信息,请参阅Pavel Minaev的答案. (2认同)

Pav*_*aev 5

这是一种常见的模式,但就个人而言,我认为没有理由滥用IDisposable,就像你可以用更明显的方式与匿名代表和/或lambdas达到同样的效果; 即:

blitter.BlitOperation(delegate
{
   // your code
});
Run Code Online (Sandbox Code Playgroud)