-1

C# 关键字 Using 实现了 Idisposable,它提供了一种释放非托管资源的机制。

现在我正在浏览这段代码

string txt = String.Empty;
      using (StreamReader sr = new StreamReader(filename)) {
         txt = sr.ReadToEnd();
      }

并且不能停止想知道,为什么在此代码中使用关键字Using ,而StreamReader是托管资源,并且垃圾收集器有责任在其范围结束后释放对象内存。

所以我的问题是,

  1. 上面的代码是否只是一种释放资源的显式处理方式
  2. 据我了解,我们在 .net 框架下使用的任何方法或类都是托管代码,那么 StreamReader 也不属于托管代码。
  3. 我是否遗漏了托管\非托管代码上的某些内容
4

2 回答 2

1

为什么在此代码中使用关键字 Using 而 StreamReader 是托管资源

虽然 StreamReader 是一个托管对象,但它可以在其中保存未在托管堆上分配的对象。垃圾收集器对其分配不可见,因此无法清理它们。对于它的特定情况,StreamReader它在内部创建一个FileStream(对于您的特定情况),它在内部创建并保存一个 WIN32 文件句柄。

_handle = Win32Native.SafeCreateFile(tempPath, fAccess, share, secAttrs, mode, flagsAndAttributes, IntPtr.Zero);

(代码参考

using只是以下的简写:

try
{
   var streamReader = new StreamReader(path);
   // code
} 
finally
{
  streamReader.Dispose();
}

实现方法IDisposable需要实现Dispose它们有机会关闭文件句柄、套接字或任何可能需要手动清理的此类资源的位置。

如果一个人选择在一个类中保存一个StreamReader,那么该类也应该实现IDisposable,以正确地将 传递DisposeStreamReader.

因此,IDisposable可以将其视为持有本机对象或持有实现 IDisposable 的对象的类的契约

于 2016-12-05T17:06:54.770 回答
-5

我认为这更像是一种防御性编码风格,我不希望将流读取器对象用作与该对象关联的文件已经使用 ReadtoEnd 函数完全读取并由 txt 引用。

于 2016-12-05T15:51:24.053 回答