如何处理实现IDiposable的对象以及在它们上调用的属性/方法的类型实现IDisposable

时间:2015-08-24 15:57:04

标签: c# .net

对于我目前正在处理的C#对象有点困惑(并且不确定)。

例如:

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

由类实现,也实现了IDisposable

   class MyClass:IMyInterface,IDisposable
   {
   }

   IMyInterface myInterface = new MyClass();

我知道如何处理实例&#34; myInterface&#34;对象MyClass(通过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]是一个字典值(其中键是string类型)和IExampleInterface类型的值,它由另一个名为ExampleClass的类实现,该类也实现了IDisposable。

   class ExampleClass:IExampleInterface,IDisposable
   {
   }

现在我的困惑是由上述条件语句引起的,因为使用专有工具分析我的代码时,myInterface.MyPathDictionary [key]导致资源/内存泄漏。我不确定的是,当我在我的C#代码的finally块中显式地处理myInterface时,我也应该明确地处理myInteface.MyPathDiciotnary [key],因为如果我已经处理了myInterface然后在它上面调用MyPathDictionary [key](myInterface)应该自动处理掉。

对此难题的任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:2)

如果MyClass拥有这些资源,那么((IDisposable)myInterface).Dispose();应该处置它们。一个普通的模式是让一次性根对象递归调用它所拥有的任何东西上的dispose。这会杀死整个对象树,这对于来电者来说既方便又直观。

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

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

另一方面,如果你真的打电话给myInterface.CreateSomething(key),那么这可能确实创造了一些必须被处理掉的东西。你需要确保这一点。要么总是处置v,无论它的价值来自哪里。或者,通过区分这两种情况。

我只需将{strong> v 打包在using中即可完成。可以轻松查看代码并得出结论是正确的。

答案 1 :(得分:0)

如果您的界面的实现需要是一次性的,处理它的最佳方法是更改​​您的界面,以便它也实现IDisposable。这样,对于需要正确处理的界面的所有用户来说都是清楚的。如果某些实现实际上并不需要处理任何可以解决的问题,那么它们只是一个空的实现。