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();
}
}