如何处置实现了IDisposable的对象,以及在这些对象上调用的属性/方法类型实现了IDisposable

本文关键字:IDisposable 对象 实现 调用 属性 方法 类型 何处置 | 更新日期: 2023-09-27 18:09:28

对我现在正在处理的c#对象有点困惑(也不确定)。

例如:

   interface IMyInterface
   {
       IDictionary<string, ICustomPath> MyPathDictionary { get; }
   }

由类实现,同时也实现了IDisposable

   class MyClass:IMyInterface,IDisposable
   {
   }
   IMyInterface myInterface = new MyClass();

我知道如何处理对象MyClass的实例"myInterface"(通过using语句或显式将实例强制转换为IDisposable,如

)
   ((IDisposable)myInterface).Dispose();
    or
    ((MyClass)myInterface).Dispose(); in the finally block after I'm done with what I'm doing.

但是我有下面的代码行

       IExampleInterface exampleInterface = some condition ? myInterface.MyPathDictionary[key]:myInterface.CreateSomething(key);

和MyPathDictionary[key]是一个字典值(其中的键是字符串类型)和IExampleInterface类型的值,它是由另一个叫做ExampleClass的类实现的,它也实现了IDisposable。

   class ExampleClass:IExampleInterface,IDisposable
   {
   }

现在我的困惑是由上面的条件语句引起的,因为用专有工具分析我的代码说myInterface。MyPathDictionary[key]导致资源/内存泄漏。我不确定的是,当我在c#代码的最后块显式地处理myInterface时,我是否应该显式地处理myInterface。MyPathDictionary[key]也一样,因为如果我已经销毁了myInterface,那么对它(myInterface)的MyPathDictionary[key]的调用应该会自动销毁。

如何处置实现了IDisposable的对象,以及在这些对象上调用的属性/方法类型实现了IDisposable

如果MyClass拥有这些资源,那么((IDisposable)myInterface).Dispose();应该处置它们。一个常见的模式是让一个可丢弃的根对象对它拥有的任何东西递归地调用dispose。这破坏了整个对象树,这对调用者来说是方便和直观的。

关键问题是 MyPathDictionary 中包含的对象是否被拥有。

您的静态分析工具可能认为myInterface.MyPathDictionary[key]是一个创建它返回的内容的工厂方法。属性获取操作是方法调用。对于工具来说,这可能看起来像一个工厂。这是一个假阳性。

另一方面,如果你实际上调用了myInterface.CreateSomething(key),那么这可能确实创建了一些必须处理的东西。你需要确保这一点。要么总是处理v,不管它的值来自哪里。或者,通过区分两种情况

我只是在using中包装 v ,然后完成它。

更容易检查代码并得出正确的结论。

如果您的接口的实现需要是一次性的,那么处理它的最佳方法是更改您的接口,以便它也实现IDisposable。这样,界面的所有用户都清楚地知道它需要被妥善处理。如果有些实现实际上不需要处理任何东西,那也没关系,它们只是有一个空的实现。