类 是否包含 return 一次性对象需要实现 IDisposable 的方法?

Do classes containing a method that return a disposable object need to implement IDisposable?

我知道通常,我们应该在包含一次性对象(字段或属性)实例的类型上实现 IDisposable。现在,这是否也适用于 类 包含 return 一次性对象的方法?

现实生活中的例子:

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

Now, does that also apply to classes containing methods that return a disposable object?

不,class 不对调用者 returns 负责。调用者必须正确处置获得的资源。

也就是说,您的第二个示例与第一个示例基本相同。 属性 没有支持字段,因此 class 没有存储对返回值的引用。事实上,编译器最终会创建一个名为 get_Image() 的方法,它与第一个示例相同。

简短的回答是否定的,您不需要实施 IDisposable

由于您返回的对象在您的 class 中没有引用,因此您 class 不再有责任处置它。

调用方需要处理。

如果您要返回一个生命周期由您的 class 管理的对象,因为属性通常是这种情况,那么您必须实现该接口。

您的 class 没有为自己保留非托管对象。它 returns 调用者的非托管对象。调用者负责非托管对象。

您的 属性 同样不会为您的 class 实例保留非托管对象。 需要 class 来实现 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) { ... }
}

您应该使用方法而不是 属性。 引用自微软的框架设计指南

[...] DO use a property, rather than a method, if the value of the property is stored in the process memory and the property would just provide access to the value. For example, a member that retrieves the name of a Customer from a field stored in the object should be a property

DO use a method, rather than a property, in the following situations: The operation is orders of magnitude slower than a field access would be. If you are even considering providing an asynchro- nous version of an operation to avoid blocking the thread, it is very likely that the operation is too expensive to be a property. In particular, operations that access the network or the file system (other than once for initialization) should likely be methods, not properties. […]

不是真的,使用接口的目的通常是确保我们不会遗漏任何东西,实现定义良好的接口始终是最佳实践,因为它们可以在长期 运行.

从技术上讲,接口 IDisposable 中只有一个 dispose 方法,您始终可以使用自己的逻辑编写自己的 Dispose 方法。

是的!如果你甚至不使用 Dispose 方法从你的记忆中放弃不必要的对象,它总是会在一天结束时由 C# 垃圾收集器处理,但我不会很高兴 我记忆中有 100 多 mb 的非托管资源。

无论如何,答案不是真的,但经常使用它,因为它使一切都保持精简。