3

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?

4

1 回答 1

6

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)
于 2009-08-31T16:50:59.000 回答