在C#中强制使用using语句是否可能?

6

我希望能够用某种属性来装饰我的类,以强制使用using语句,以便始终安全地处理并避免内存泄漏。有人知道这样的技术吗?


把您的对象嵌入到另一个可处理的对象中怎么样? - Anton Tykhyy
使用IDisposable修饰你的类,旨在向你的类的消费者传达一个信号,告诉他们应该将其包装在Using中或调用Dispose。如果你强制使用“Using”技术,实际上就是在告诉你的好消费者:“我认为你太蠢了,不会调用Dispose”,并限制了使用方式。 - Damien_The_Unbeliever
我还想说,你确定没有场景需要在一个方法中创建对象,在另一个方法中释放它吗?(也许它们也是IDisposable)。你这样做会使得别人无法实现这个需求。 - Damien_The_Unbeliever
@Damien_The_Unbeliever 我相信使用 using 块也可以确保即使出现异常,Dispose 也会被调用。使用 using 有很多好处,我可以理解想要强制执行它。 - Wedge
@Wedge,是的,没错。但如果从来没有理由要在Using语句块之外使用IDisposable,我想编译器会出现警告/错误。因此我的评论提到确保您不要忽视可能的情况。 - Damien_The_Unbeliever
其实是我太蠢了。我使用了一个第三方库,没注意到其中有一个类实现了IDisposable,由此导致应用程序存在内存泄漏问题。因此,为了避免在自己的代码中犯同样的错误,我向社区寻求答案。真是我太傻了! - Bigtoe
3个回答

13

嗯,有一种方法可以做到这一点 - 只允许通过一个接受委托的静态方法访问您的对象。以下是一个非常简化的示例(显然,有许多不同的打开文件的方法 - 读取/写入等):

public static void WorkWithFile(string filename, Action<FileStream> action)
{
    using (FileStream stream = File.OpenRead(filename))
    {
        action(stream);
    }
}

如果只有你自己类中的方法能够创建一个可处理的对象实例,你可以确保它们被适当地使用。当然,委托可能会复制引用并尝试以后使用它,但那不是完全相同的问题。

当然,这种技术严重限制了你对该对象的操作 - 但在某些情况下它可能很有用。


2
我觉得做类似这样的事有点不太好。现在感觉好多了,因为有Skeet的认可 - Andrew Bullock
这并不是一个“新”的模式,我现在也想不起它的名字了... - Jon Skeet

3
你可以使用 FxCop 来执行此规则。参见维基百科,获取快速概述

1
当人们正在使用他的类时,这并没有帮助-他不能告诉他的用户使用FxCop。 - ChrisF
使其成为构建的一部分,他们必须注意它。 - Michael Hedgpeth

0

如果您想确保对象始终被处理,请在IDisposable中使用finalizer。

但在此之前,请先了解IDisposable和finalizer,并意识到通常情况下,除非您的类正在执行类似于管理未托管资源的生命周期之类的操作,否则您通常不需要它们。

使用finalizer,无论是否包装在using语句中,都将最终回收您的对象。using语句是IDisposable的一种便利方式,允许进行确定性清理。唯一的注意事项是具有finalizer的对象更昂贵,而且通常在等待最终处理时会在内存中停留更长时间。

参考 何时需要实现finalizer或IDisposable?技术难题:使用Dispose、Finalizers和IDisposable


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接