c# - 处理处理 IDisposable 对象的通用函数

标签 c# generics idisposable

我正在处理一个处理大量 Sql 对象的类 - Connection、Command、DataAdapter、CommandBuilder 等。在多个实例中我们有这样的代码:

if( command != null )
{
    command.Dispose();
}

if( dataAdapter != null )
{
    dataAdapter.Dispose();
}

etc

我知道这在复制方面是相当不够的,但它已经开始有味道了。我认为它有味道的原因是因为在某些情况下该对象也被设置为 null。

if( command != null )
{
    command.Dispose();
    command = null;
}

如果可能的话,我很乐意摆脱重复。我想出了这个通用方法来处理对象并将其设置为 null。

private void DisposeObject<TDisposable>( ref TDisposable disposableObject )
    where TDisposable : class, IDisposable
{
    if( disposableObject != null )
    {
        disposableObject.Dispose();
        disposableObject = null;
    }
}

我的问题是...

  1. 这个通用函数是个坏主意吗?
  2. 是否需要将对象设置为null

编辑:

我知道 using 语句,但是我不能总是使用它,因为我有一些成员变量需要持续超过一次调用。例如连接和事务对象。

谢谢!

最佳答案

您应该考虑是否可以使用 using 语句。

using (SqlCommand command = ...)
{
    // ...
}

这确保当控制离开使用范围时,Dispose 在命令对象上被调用。与您自己编写清理代码相比,这有很多优点:

  • 更简洁。
  • 变量永远不会设置为 null - 它是在一条语句中声明和初始化的。
  • 当对象被处置时,变量超出范围,因此您可以降低意外尝试访问已处置资源的风险。
  • 它是异常安全的。
  • 如果您嵌套 using 语句,那么资源自然会以正确的顺序放置(与创建它们的顺序相反)。

Is it necessary to set the object to null?

通常不需要在使用完变量后将其设置为空。重要的是您在使用完资源后调用 Dispose。如果你使用上面的模式,不仅没有必要将变量设置为 null——它会给出一个编译错误:

Cannot assign to 'c' because it is a 'using variable'

需要注意的一点是,using 只有在同一方法调用中获取和释放对象时才有效。如果您的资源需要在多个方法调用期间保持事件状态,则不能使用此模式。在这种情况下,您可能希望让您的类实现 IDisposable 并确保在调用 Dispose 方法时清理资源。在这种情况下,您将需要您编写的代码。在这种情况下将变量设置为 null 并没有错,但这并不重要,因为垃圾收集器无论如何都会正确清理内存。重要的是确保在调用 dispose 方法时释放您拥有的所有资源,并且您正在这样做。

一些实现细节:

  • 您应该确保如果您的 Dispose 被调用两次,它不会抛出异常。您的效用函数可以正确处理这种情况。
  • 您应该确保您对象上的相关方法引发ObjectDisposedException。如果您的元素已被处置。

关于c# - 处理处理 IDisposable 对象的通用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3189854/

相关文章:

c# - 如何让Silverlight UserControl填充网页?

c# - System.MissingMethodException Message=未找到方法 : DryIoc. 规则 DryIoc.Rules.WithoutFastExpressionCompiler()

java - 如何实现通用方法

c# - Entity Framework Core 不支持具有多对多关系的通用抽象实体

c# - System.ServiceModel.ServiceHost 实现 IDisposable 但 Dispose 不公开

c# - 从单轨铁路到 ASP.Net MVC

c# - 使用 C# 从字符串中提取数字

java - 以下泛型声明在 Java 中有何不同?

c# - 为什么要处理一个肯定会很快被处理掉的对象呢?

c# - 如果在处置之前复制 IDisposable 的引用,IDisposable 是否仍会被处置?