我知道,作为一项规则,我们应该对包含一次性对象(字段或属性)实例的类型实现IDisposable
。现在,这是否也适用于包含返回一次性对象的方法的类?
现实生活中的例子:
class MyClass
{
public Image GetImage()
{
using (var stream = new MemoryStream(byteArray))
using (var img = Image.FromStream(stream))
{
return new Bitmap(img);
}
}
}
如果答案是否定的,那么前面的代码与以下代码之间的区别是什么?
只读属性而不是方法:
class MyClass
{
public Image Image
{
get
{
using (var stream = new MemoryStream(byteArray))
using (var img = Image.FromStream(stream))
{
return new Bitmap(img);
}
}
}
}
答案 0 :(得分:3)
现在,这是否也适用于包含返回一次性对象的方法的类?
不,该类不对其返回给调用者的任何内容负责。调用者必须正确处理获得的资源。
那就是说,你的第二个例子与第一个例子基本相同。该属性没有支持字段,因此该类不存储对返回值的引用。实际上,编译器最终将创建一个名为get_Image()
的方法,该方法与第一个示例相同。
答案 1 :(得分:3)
您的类不会为自己保留非托管对象。它将非托管对象返回给调用者。调用者负责非托管对象。
您的属性同样不会保留您的类实例的非托管对象。 要求您的类实现IDisposable
的属性实现看起来像这样:
class MyClass : IDisposable
{
public Image Image { get; }
public MyClass(byte[] byteArray)
{
using (var stream = new MemoryStream(byteArray))
using (var img = Image.FromStream(stream))
{
Image = new Bitmap(img);
}
}
public void Dispose() { ... }
public virtual void Dispose(bool disposing) { ... }
}
答案 2 :(得分:2)
简短回答是否定的,您不需要实施IDisposable
。
由于您要返回一个您的班级中没有参考的对象,因此您的班级不再需要处理它。
来电者必须处理它。
如果您要返回一个对象,其生命周期由您的类管理,就像属性一样,那么您必须实现该接口。
答案 3 :(得分:2)
您应该使用方法而不是属性。 引用微软框架设计指南
[...]如果属性的值,请使用属性而不是方法 存储在进程内存中,属性只是提供 获取价值。例如,检索名称的成员 来自存储在对象中的字段的客户应该是属性
在以下情况下,请使用方法而不是属性: 该操作比现场访问慢几个数量级 将会。如果您甚至考虑提供异步 一个操作版本,以避免阻塞线程,它是非常的 可能该操作太昂贵而无法成为财产。在 特别是访问网络或文件系统的操作 (除了一次初始化)应该是方法,而不是 属性。 [...]
答案 4 :(得分:1)
不是真的,使用接口的目的通常是确保我们不会错过任何东西,实现定义良好的接口始终是最佳实践,因为从长远来看它们可以为您节省很多麻烦。 / p>
从技术上讲, IDisposable 界面中只有一个dispose方法,您可以随时使用自己的逻辑编写自己的 Dispose 方法。
是的,是的!如果您甚至不使用Dispose方法从内存中放弃不必要的对象,那么它将在一天结束时由C#垃圾收集器处理,但我对 100+不会感到满意mbs 的非托管资源在我的记忆中。无论如何,答案不是真的,而是经常使用它,因为它可以简化所有事情。