When to Dispose?

8

我对所有关于IDispose和“using”语句的讨论感到困惑。我想知道在下面的测试示例中是否需要使用“using”语句或某种IDispose实现...

public class Main()
{
    MyFile myFile = new MyFile("c:\subdir\subdir2\testFile.txt");
    Console.Writeline("File Name: " + myFile.FileName() + "File Size: " + myFile.FileSize());
}

public class MyFile
{
    private FileInfo _fInfo;

    public MyFile(string fullFilePath)
    {
        _fInfo = new FileInfo(fullFilePath);
    }

    public string FileName()
    {
        return _fInfo.Name;
    }

    public long FileSize()
    {
        return _fInfo.Length;
    }

}

首先,在C# .NET中,你永远无法确定是否已经处置了任何对象。GC将为您完成这项工作。您可以在析构函数中告诉一些东西,但它仍然无法根据您的意愿释放内存。其次,使用using语句比创建代码和实现IDisposable或创建可处理的方法更加清晰。由于using语句的作用域到达结尾时,所有在其中定义和初始化的变量都将被销毁。 - user900360
9
@AnubhavSaini说的不正确。GC不会自动为你处理对象的释放,只有当你调用Dispose方法时才能确保已经释放了对象。请注意,Dispose方法是由开发人员手动调用的。 - John Saunders
GC收集。处理处理。调用Dispose方法将确保您已处理。当它被处理时,没有人知道。仍然运行时销毁对象。在大多数情况下,请使用Using语句并尝试编写异常安全的Disposing函数。@JohnSaunders谢谢。 - user900360
6
你仍然是错误的。当你调用 Dispose 方法时,对象会被立即处理掉。你把垃圾回收和处理弄混了。 - John Saunders
可能是IDisposable接口的正确使用方式的重复。 - John Saunders
4个回答

22

不需要实现 IDisposable,因为你的示例未使用任何需要处理的资源(它未接触任何实现 IDisposable 的内容,也没有直接句柄到非托管资源)。

但是,如果你更改了类以打开文件,并维护一个引用打开文件句柄的 FileStream 字段,那么实现 IDisposable 来关闭流就有意义了。


在你在这里的时候,能否解释一下“using()”和“dispose()”方法之间的相似之处的部分?我记得还有另一个问题,Lippert说它们之间几乎没有差别,但我不记得具体是什么了。 - mowwwalker
5
using语句等同于一个try/finally块,在finally块中进行资源释放。 - Jon Skeet

7

在提供的代码中,我没有看到任何需要释放的资源。所以答案是不需要这个代码中使用它。


6
在你的例子中没有需要处理的内容,所以你不需要这样做。
如果你想读/写文件,你可以使用Streamreader/Streamwriter,但是在使用完后需要处理这些对象。
using(StreamReader sreader=new StreamReader())
{
//your code
}

在这种情况下,使用语句将帮助您不必考虑手动处理/关闭对象。


如果我添加了以下代码行会怎样呢?string[] fileEntries = Directory.GetFiles(dirPath); - Ann Sanderson
1
不需要再次处理。在我的示例中,您不会创建需要处理的对象,例如StreamReader :) - Chuck Norris

4

在您的代码中不需要任何的Dispose / using - 有关IDisposable的详细指南,请参见此处


2
那个链接是使用IDisposable接口的最佳解释! - ganders

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