C# 为什么我需要调用stringreader和stringwriter上的dispose?

C# 为什么我需要调用stringreader和stringwriter上的dispose?,c#,idisposable,C#,Idisposable,它从我读一本书开始 StringWriter实现公共抽象类TextWriter:MarshallByRefObject,IDisposable 上面写着: 该框架提供了System.IDisposable接口,该接口应 实现以向开发人员提供手动方式来释放非托管 一旦不需要资源,就立即提供资源 但是什么是非托管资源?我显然不认为StringWriter符合条件。如果我自己编写而不继承IDisposable…我认为没有必要添加Dispose() 事实上,我使用visual studio内存调试器进行

它从我读一本书开始


StringWriter
实现
公共抽象类TextWriter:MarshallByRefObject,IDisposable

上面写着:

该框架提供了System.IDisposable接口,该接口应 实现以向开发人员提供手动方式来释放非托管 一旦不需要资源,就立即提供资源

但是什么是非托管资源?我显然不认为
StringWriter
符合条件。如果我自己编写而不继承IDisposable…我认为没有必要添加
Dispose()

事实上,我使用visual studio内存调试器进行了测试: 函数返回后,
StringWriter
及其
StringBuilder
将被释放…此外,调用dispose似乎对StringWriter没有任何作用


因此,并非所有继承自
IDisposable
的类都具有有用的
Dispose
。这又回到了我的问题什么被认为是非托管资源(请举例说明)。我听说文件就是其中之一…但CLR不是VM吗?…每个资源都应该由它来管理,非
StringWriter
继承自抽象的
TextWriter
,它实现了
IDisposable
,并且有一些子类确实有非托管资源,如流、文件句柄、,因此,可以安全地处理
TextWriter
的任何子类,而不必担心是否需要处理


因此,处置
StringWriter
实际上可能不会做任何事情(类似于
DataSet
),但处置任何实现
IDisposable
StringWriter
的东西仍然是一种很好的做法,它是实现
IDisposable
TextWriter
的后代,可能是因为大多数
文本编写器将拥有非托管资源。如果您收到一个
TextWriter
,但不知道它来自何处(即它可能是
TextWriter
的任何后代),
TextWriter
实现
IDisposable
这一事实允许您正确管理它拥有的任何非托管资源。您可以编写代码,接受任何
TextWriter
,在不再需要编写器时调用
Dispose
,并相信一切都会清理干净。

您对“什么是非托管资源”的问题已经有了答案:标题中的问题或多或少在中得到了回答(关于MemoryStream的相同问题).我把它作为的副本合上了,在这两者之间,我回答了两个问题。我不明白为什么这个问题要合上。StringReader/StringWriter不需要处理。从O'reilly的C#简言之:“这些类型是在基类的胁迫下,而不是在真正需要执行基本清理的情况下,一次性使用的。如果您碰巧在一个方法中完全实例化和处理这样一个对象,那么将其包装在一个using块中不会带来什么不便。但是,如果对象的持续时间更长,那么跟踪它何时不再使用,以便您可以处理它会增加不必要的复杂性。在这种情况下,您可以忽略对象处理。”我不同意。调用不起任何作用的代码不是一种好的做法。实际上这是一种不好的做法。编程语言是“处理”的工具"; 不要等待或什么都不做。@Darkonekt是否有任何保证,在dotnet core、mono、任何wasm实现和当前、过去和将来的每个版本的完整框架上,Dispose函数永远不会做任何事情,也不需要它?如果有一些财团能够确保这一点,那么我会考虑不使用这些语句包装这些类。如果不能保证,那么我认为你的最后一句话是危险的。@Darkonekt我错过了这句话,否则我会对你的这句话做出类似的回应
IDisposable
是一种合同,在该合同中,当处理完对象时,所有者需要调用
Dispose
。调用方不应该假设方法是否实际执行任何操作。另外,
StringWriter
的某些自定义子类确实在它的
Dispose
中做了一些事情,这是完全合理的,因此如果您选择不对其进行校准,则可能会导致资源泄漏。@DStanley您现在想知道“如果”。。。。事实上,调用不做任何事情的代码是不正确的。这是多余的。没有什么要求代码需要调用接口的每个成员。在这种情况下,我认为接口是错误的,因为对象没有可丢弃的对象,所以没有必要实现这种“契约”。仅仅因为别人做错了,并不意味着你也必须这样做。
class ConfusedDevStringWriter{
   private StringBuilder sb;
   public ConfusedDevStringWriter(){ //ctor
      sb = new StringBuilder();
   }
}