处理嵌套的一次性物品?

我想知道是否有关于处理嵌套在另一个一次性物品内的一次性物品的约定(在财产/公共领域,而不是私人成员)。 例如,DataSet包含DataTable,SqlCommand包含SqlConnection。

显而易见的是,一个class级处理它拥有的所有Disposable物品,剩下的就是其余部分。 是否存在这样的惯例? 如果是这样,.NET库如何确定谁拥有什么? 如何确定是否正在处理嵌套对象?

PS:我一直想知道这个问题,显然有其他问题: 调用SqlCommand.Dispose时会出现什么问题?

编辑1:发现配置DataSet,不配置其表。

// Fill dataset from sqldataadpater. foreach (DataTable dt in dataSet.Tables) { dt.Disposed += Program.DisposedEventHandler2; } Console.WriteLine("Disposing dataset"); dataSet.Dispose(); //Event not fired here. Console.WriteLine("Disposing datatables maually"); foreach (DataTable dt in dataSet.Tables) { dt.Dispose(); //Event fired here } #endregion 

我通常遵循的经验法则是,创建一次性物体的类也将处置它。 例如: SqlCommand不会释放它的连接,因为它没有创建它。 StreamReader在这个意义上有一个奇怪的行为,因为它总是会处理底层流,即使它是从外部提供的(我觉得这很烦人,如果你喜欢微软来解决这个问题,请在这里投票)。

我会说通常一个容器会处理任何包含的一次性物品 – 例如StreamReader处理底层流 – 但通常我会用一个单独的using语句处理每个项目。

任何“所有权”的概念实际上只是在文档和惯例中。 基本上你必须知道什么会处理什么,这通常意味着阅读文档并希望它清楚地说明。 不幸的是,它并不总是这样:(

请注意,这里没有单一的正确答案 – 有时您可能希望某种类型表现一种方式,有时则另一种方式。 某些类型明确允许您说明您是否有效地转移了资源的所有权,尽管大多数情况下没有。

最好的方法通常是为嵌套的IDisposable项提供一个指示,指示嵌套项是否应与容器一起处理,除非该项的使用寿命永远不会超过容器的使用寿命(在这种情况下,处置容器可以处理容器) item),或者可以确定除容器之外的最后一个实体需要包含的物品将知道它的存在和需要处置(意味着容器不必担心处置,因为其他项目可以处理它)。

举一个简单的例子,假设有人正在设计一个UI框架,并希望提供一个应该显示Picture的控件,并提供一种代码可以提供要显示的图像的方法。 进一步假设某些类型的Picture具有需要处理的资源。 在某些情况下,代码可能希望在多个控件上显示某个Picture ,这些控件可能并非全部同时处理。 在这种情况下,如果处置一个控件来处理它的图片就不好了。 另一方面,在其他情况下,代码可能会为了显示而创建图片,将其提供给控件,然后不再关心它。 在这种情况下,提供图片的代码可能知道当控件不再需要时应该放置图片,但可能不知道何时会发生。

使用参数来指示图片是否应该是Disposed将允许在上述两种情况下都使用干净的代码。 另一种方法是Winforms使用的方法,即在控件的图片更改或Image属性更改时发生的事件。 将控件的Image属性设置为需要处理的图像的代码可以使用这些事件来处理它。