views:

66

answers:

1

Potentially embarrassing question, but there is obviously something I'm missing that I want/need to know.

I expect the following code to create a new table row with new cells to be rendered later. And that's what it does ... as you would expect.

using (TableRow tr = new TableRow())
{
    using (TableCell td = new TableCell())
    {
     td.Text = "Column A";
     tr.Cells.Add(td);
    }
    using (TableCell td = new TableCell())
    {
     td.Text = "Column B";
     tr.Cells.Add(td);
    }
    tbl.Rows.Add(tr);
}

But .... but aren't the TDs created in the using statements invalidated once they go out of the 'using' scope? Wouldn't the TD objects referenced by the row now be invalid and shouldn't the row fail when it attempts to use them? The same could be said for the TR when it's rendered by the 'tbl' object.

Do I not understand dispose?

Do I not understand using?

Is TableRow.Cells.Add() actually doing a deep copy not just a ref ptr copy?

Can the TableCell actually be used after it's disposed?

What gives?

+6  A: 

All the "using" block does is ensure that the object's "Dispose" method is called at the end of the block. Objects can still be used accessed after they are disposed, but it's up to their implementation of the "Dispose" method to know if anything bad will happen if this is done.

In this case, it doesn't look like the "Dispose" method on TableRow & TableCell does anything that prevents them from being used in the future. That's why you don't have any problems.

Since you do want the objects to be used in the future, you shouldn't put them in "using" blocks at all. The parent page object should dispose of the controls at the end of the page lifecycle.

Edit: I made a test server control and put a breakpoint in its "Dispose" event. Here's the stack trace that shows .Net calling dispose for you. You can use Reflector to look at the code in more detail.

at TestControl.Dispose() in D:\TestControl.cs:line 25  
at System.Web.UI.Control.UnloadRecursive(Boolean dispose)   
at System.Web.UI.Control.UnloadRecursive(Boolean dispose)   
at System.Web.UI.Control.UnloadRecursive(Boolean dispose)  
at System.Web.UI.Control.UnloadRecursive(Boolean dispose) 
at System.Web.UI.Page.UnloadRecursive(Boolean dispose)  
at System.Web.UI.Page.ProcessRequestCleanup()   
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)   
at System.Web.UI.Page.ProcessRequest()   
at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)   
at System.Web.UI.Page.ProcessRequest(HttpContext context)
David
Thanks David, to be honest, I can't think of any reason these objects would even be disposable. As far as not disposing them, is it safe to assume the parent object will always dispose of disposable objects? I'm not so sure how comfortable I am with that.
John MacIntyre
The Page will Dispose the Controls after rendering.
Henk Holterman
Does the Page object dispose all controls? Does anybody have a link for that? thx
John MacIntyre
Yes, the page object will dispose all controls. See the stack trace I've added to the my answer.
David