不好的做法? C# using 语句的非规范用法

问题描述 投票:0回答:6

C# 有

using
语句,专门针对 IDisposable 对象。据推测,
using
语句中指定的任何对象都将持有某种应确定性释放的资源。

然而,在我看来,编程中的许多设计都有单一的、明确的开始和结束,但缺乏内在的语言支持。

using
构造提供了使用代码编辑器的内置功能的机会,至少可以清晰自然地突出显示此类设计或操作的范围。

我想到的是经常以

BeginXXX()
EndXXX()
方法开始的操作,尽管有很多不同的风格,例如涉及“开始”和“连接”的异步代码执行.

举这个简单的例子。

webDataOperation.Start();
GetContentFromHardDrive();
webDataOperation.Join();
// Perform operation that requires data from both sources

如果 Start 方法返回一个对象,而该对象的

IDisposable.Dispose
方法执行连接操作,该怎么办?

using(webDataOperation.Start()) {
    GetContentFromHardDrive();
}
// Perform operation that requires data from both sources

或者,更好的是,我具体想到的是:我有一个对象,它执行高度专业化的图形位块传输,并具有

Begin()
End()
方法(DirectX 和 XNA 中也存在这种设计)。相反...

using(blitter.BlitOperation()) {
    // Do work
}
// Use result

它似乎更自然和可读,但它是否不可取,因为它使用了

IDisposable
接口和
using
语句来达到意想不到的目的?换句话说,这是否与以非直观方式过度加载运算符相同?

c# using-statement
6个回答
20
投票
框架设计指南

建议这样做。 基本上,如果类型包装具有特定生命周期的操作,则使用 IDisposable 和 using 语句就成为值得考虑的合适事情。

我实际上也在博客中讨论了

这个特定主题


12
投票

我属于少数派。大多数人似乎使用“使用”作为通用目的“即使抛出异常,我也希望运行一些清理代码”机制。

我不喜欢这个,因为(1)我们已经有一个机制,称为“try-finally”,(2)它使用一个功能来实现它不想要的目的,以及(3)如果调用清理代码很重要,那么为什么它在被调用的地方不可见呢?如果它很重要,那么我希望能够看到它。


6
投票

基本的经验法则:如果我可以阅读你的代码并理解它在做什么以及你的意图是什么,那么它是可以接受的。另一方面,如果您需要解释您做了什么,或者为什么这样做,那么维护代码的初级开发人员可能会遇到麻烦。

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

底线:这种“技术”不会给你带来任何好处,只会让其他开发人员感到困惑。


5
投票

blitter.BlitOperation(delegate { // your code });



2
投票


0
投票

Wes Deyer 在他的 LINQ to ASCII Art 程序中使用了它,他称其为一次性操作(Wes 在 C# 编译器团队工作 - 我相信他的判断:D):

http://blogs.msdn.com/wesdyer/archive/2007/02/23/linq-to-ascii-art.aspx

class ActionDisposable: IDisposable { Action action; public ActionDisposable(Action action) { this.action = action; } #region IDisposable Members public void Dispose() { this.action(); } #endregion }

现在您可以从函数返回它,并执行如下操作:

using(ExtendedConsoleWriter.Indent()) { ExtendedConsoleWriter.Write("This is more indented"); } ExtendedConsoleWriter.Write("This is less indented");

© www.soinside.com 2019 - 2024. All rights reserved.