C# CA2000 Dispose Object Before Losing Scope

3.9k views Asked by At

This is my code, it gives me CA2000 on "new DataTable()..." and "new DataColumn()..."s

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

Is it possible to fix without declaring variables?

1

There are 1 answers

7
Peter Duniho On BEST ANSWER

This is nearly a duplicate of How to fix a CA2000 IDisposable C# compiler warning, when using a global cache. Maybe it should be considered a duplicate of that one. I'm not sure.

Code Analysis is legitimately complaining that it is theoretically possible for the method to complete without the IDisposable object being disposed and without it being safely stored somewhere else. The latter can happen if an exception occurs during the initialization of the DataTable object or adding the DataTable object to the usersDS.Table object (whatever that is).

If you can guarantee that no exception will be thrown here, then IMHO it is perfectly fine to suppress the CA warning. In that case, you know more than CA can, and you're promising you know what you're doing.

If you can't make the guarantee, then no…it's not possible to fix the warning without introducing local variables so that you're able to dispose the object in the event of an exception. For example:

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;
}