【问题标题】:C# CA2000 Dispose Object Before Losing ScopeC# CA2000 在失去作用域之前处理对象
【发布时间】:2014-11-23 04:36:36
【问题描述】:

这是我的代码,它在“new DataTable()...”和“new DataColumn()...”上为我提供 CA2000

usersDS.Tables.Add(new DataTable()
{
    TableName = "Users",
    Columns = { new DataColumn() { ColumnName = "Handle", DataType = typeof(string) }, new DataColumn() { ColumnName = "Nickname" ,DataType = typeof(string) } }
});

是否可以在不声明变量的情况下进行修复?

【问题讨论】:

标签: c# optimization analysis ca2000


【解决方案1】:

这几乎是How to fix a CA2000 IDisposable C# compiler warning, when using a global cache 的副本。也许它应该被认为是那个的副本。我不确定。

代码分析合法抱怨理论上可以在不处置 IDisposable 对象且不将其安全存储在其他地方的情况下完成该方法。如果在初始化DataTable 对象或将DataTable 对象添加到usersDS.Table 对象(无论是什么)期间发生异常,则可能会发生后者。

如果你可以保证这里不会抛出异常,那么恕我直言,抑制 CA 警告是完全可以的。在这种情况下,您比 CA 知道的更多,并且您承诺您知道自己在做什么。

如果您不能做出保证,那么就不行……如果不引入局部变量,就无法修复警告,这样您就可以在发生异常时处理对象。例如:

DataTable dataTable = null;
DataColumn dataColumn1 = null, dataColumn2 = null;

try
{
    dataColumn1 = new DataColumn() { ColumnName = "Handle", DataType = typeof(string) };
    dataColumn2 = new DataColumn() { ColumnName = "Nickname", DataType = typeof(string) };
    dataTable = new DataTable()
    {
        TableName = "Users",
        Columns = { dataColumn1, dataColumn2 }
    };
    usersDS.Tables.Add(dataTable);
}
catch
{
    if (dataTable != null)
    {
        dataTable.Dispose();
    }
    if (dataColumn1 != null)
    {
        dataColumn1.Dispose();
    }
    if (dataColumn2 != null)
    {
        dataColumn2.Dispose();
    }
    throw;
}

【讨论】:

  • “代码分析合理地抱怨说,理论上可以在不释放 IDisposable 对象的情况下完成该方法”——这确实是可能的,但它不是任何类的合理抱怨Dispose() 没有任何意义。正如 cmets 中所指出的,即使 DataTableDataColumn 实现了 IDisposable,这并没有真正做任何有用的事情,并且这些类应该被设计为不实现IDisposable。我们无法解决这个问题。不过,我们可以避免对他们的 Dispose() 方法进行毫无意义的调用。
  • DataTableDataColumnIDisposable 中没有有意义的操作这一事实是一个实现细节。 IE。它不是DataTableDataColumn 合同的一部分,理论上将来可能会发生变化。我更喜欢编写公共合约的代码,而不是私有实现,恕我直言,最好继续处理 IDisposable 对象,无论您对它们的私有实现细节了解多少。 YMMV。
  • 一般来说这是有道理的,但在这种情况下,意义不大。不仅如此,您的答案是基于这样的假设,即一旦将数据表和列添加到数据集中,就可以不处理它们,大概是因为处理数据集也会处理包含的表和列,但是一个数据集没有这样做,它的文档也没有声称这样做。按照你自己的逻辑,你自己建议的做法是不对的。
  • 真的吗?你想为此大吵一架吗?即使这里的示例中甚至没有“数据集”?即使System.Data.DataSet 类型是作为包含DataTableDataColumn 的同一库的一部分编写的? IE。如果对DataTable 和/或DataColumn 进行了更改,那么作者也可以轻松地更新同一库中的代码 以匹配,这对于用户代码而言并非如此。真的吗?哦,好吧......就像我说的:你的里程可能会有所不同。欢迎您发表意见。
  • 我假设usersDS 被命名为usersDS,因为它是“用户”DataSet。对不起,如果这个假设结果不正确。顺便说一句,您可能想对(再次)linked question 上的一些答案进行投票:投票最多的答案不同意您的观点,但其他一些答案可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
  • 2018-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多