【问题标题】:Does "using" also dispose objects created in the constructor? [duplicate]“使用”是否也会处理在构造函数中创建的对象? [复制]
【发布时间】:2016-06-15 13:15:41
【问题描述】:

当创建一个实现IDisposable 的元素时,Dispose() 会在using 块的末尾被调用,如果我没记错的话,如果抛出异常的话。

但是,当在一次性元素的构造函数中创建ClassB 的新元素时,如果实现了IDisposable,ClassB 的对象是否也会被释放?

using (ClassA a = new ClassA(new ClassB()))
{
}

这可能适用于与Stream 相关的类。 但是,这是否普遍适用?

【问题讨论】:

  • 没有。它不是在构造函数中创建的,而是在构造函数之前创建的。
  • 如果是这样的话,那就糟了。您可以创建一个实现 IDisposable 的 ClassB 并使用与此问题一样多的击键进行测试。

标签: c# .net idisposable using-statement


【解决方案1】:

ClassB 只会被释放如果ClassA 的 dispose 方法调用 dispose。

class ClassA : IDisposable
{
    private ClassB b;
    public ClassA (ClassB b) { this.b = b; }
    public void Dispose() { this.b.Dispose(); }
}

如果没有,您需要单独处理:

using (ClassB b = new ClassB())
using (ClassA a = new ClassA(b))
{
}

【讨论】:

  • 即使在第一种情况下,ClassA 构造函数中的异常也会导致 ClassB 实例泄漏。
  • 所以最好不要信任任何类......有没有办法找出一个类是否也处理它的构造函数参数而不是反编译?流似乎可以做到这一点。但是有一个通用的模式吗?
  • @bytecode77 如果它被记录为处置资源,假设它会处置它。如果它没有明确声明它确实如此,则假设它没有。
  • @bytecode77,实际上处置注入的对象并不是一个好习惯。此答案中的示例 1 是一个错误的决定。如果ClassB 对象在多个ClassA 实例之间共享怎么办?
  • 应该多次调用 Dispose 是安全的,所以即使 ClassA 确实处理了 ClassB,如果您使用第二个示例,它应该不会导致问题
【解决方案2】:

简短的回答,不。如果ClassB 实现了IDisposable,你也应该将它包装在 using 块中:

using (var b = new ClassB())
using (var a = new ClassA(b))
{
    // do stuff
}

请记住,您传递给构造函数或任何其他接受参数的方法的所有内容都会在调用构造函数或方法之前进行评估。

有些类,比如StreamWriterStream 进行处理,会处理通过构造函数传递的任何内容,但通常将处理留给实际实例化对象的人。

【讨论】:

    猜你喜欢
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    • 2021-07-16
    • 2013-06-20
    • 1970-01-01
    相关资源
    最近更新 更多