0

I have code that creates a DataTable and returns it, like this:

public static DataTable Transpose(DataTable input)
{
    DataTable transpose = new DataTable();

    // first column name remains unchanged
    transpose.Columns.Add(input.Columns[0].ColumnName); 

    for (int i = 1; i < input.Columns.Count; i++)
    {
        // all other column names become first row
        transpose.Rows.Add(new object[] { input.Columns[i].ColumnName }); 
    }

    for (int j = 0; j < input.Rows.Count; j++)
    {
        // all row values in column 0 are now column names
        transpose.Columns.Add(input.Rows[j][0].ToString()); 

        for (int i = 1; i < input.Columns.Count; i++)
        {
            transpose.Rows[i - 1][j + 1] = input.Rows[j][i].ToString();
        }
    }

    return transpose;
}

I get this warning on Code Analysis: CA2000: Dispose objects before losing scope

Of course the warning is easily fixed by using a using:

public static DataTable Transpose(DataTable input)
{
    using(DataTable transpose = new DataTable())
    {
        // same stuff here

        return transpose;
    }
}

But why?
(a) Why's the original code throwing the warning?
(b) Is it safe to return the variable declared within using, from inside the using block?

SNag
  • 17,681
  • 10
  • 54
  • 69
  • I don't get any warning, what version of visual studio do you use? – Jakob Sep 16 '15 at 12:14
  • 1
    (a) You get the warning because the code between `transpose = new() ...` and `return transpose` can throw. This will leave the local `transpose` undisposed, so you need to do that in `try-finally`. See [duplicate](http://stackoverflow.com/questions/6684206/how-to-fix-a-ca2000-idisposable-c-sharp-compiler-warning-when-using-a-global-ca). (b) [No](http://stackoverflow.com/questions/2822687/return-the-variable-used-for-using-inside-the-using-c-sharp). You'll get an `ObjectDisposedException` when trying to use the returned `DataTable`, or worse. – CodeCaster Sep 16 '15 at 12:17
  • @Jakob: I'm on VS 2012 Premium. – SNag Sep 16 '15 at 12:23
  • 1
    The only real problem you have right now is using a tool that you are not ready to understand. Undo that code change and study the subject. Questions about it can wait until you understand it better, pretty important if you want to have a shot at understanding an answer. – Hans Passant Sep 16 '15 at 12:24
  • 1
    CA2000 is notorious for false positives. They've tried to pack some heuristics into it to avoid those false positives and managed to get rid of some only to get others in return. Try for instance naming your method GetTranspose and CreateTranspose and see if there's a difference (don't change any other code). But yes, fix first what @CodeCaster mentions, this is a real bug. – Lasse V. Karlsen Sep 16 '15 at 13:35
  • And no, it is **not** a fix to dispose the object before returning it. By definition, after disposing the object it should no longer be used, you should **not** return it. Handle exceptions, and that's it. – Lasse V. Karlsen Sep 16 '15 at 13:36
  • Thanks all! I've undone my change (removed the `using`) and flagged off the warning as a false-positive to a senior reviewer. @HansPassant, I will take your advice and study the subject in detail. – SNag Sep 16 '15 at 13:44

0 Answers0