Почему родительский объект не завершается с ранее удаленным дочерним объектом?

Потенциально неловкий вопрос, но я, очевидно, кое-что упускаю, что хочу / должен знать.

Я ожидаю, что следующий код создаст новую строку таблицы с новыми ячейками, которые будут отображаться позже. И это то, что он делает... как и следовало ожидать.

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

Но.... но разве TD, созданные в операторах using, не становятся недействительными после того, как они выходят из области использования? Разве не будут недействительными объекты TD, на которые ссылается строка, и не должна ли строка завершиться ошибкой, когда она пытается их использовать? То же самое можно сказать и о TR, когда он отображается объектом 'tbl'.

Я не понимаю, распоряжаться?

Я не понимаю, используя?

Действительно ли TableRow.Cells.Add() делает глубокую копию, а не просто контрольную копию?

Можно ли использовать TableCell после его утилизации?

Что дает?

1 ответ

Решение

Все, что делает блок "using", это гарантирует, что метод "Dispose" объекта вызывается в конце блока. Доступ к объектам по-прежнему можно получить после их утилизации, но их реализация метода "Dispose" зависит от того, произойдет ли что-нибудь плохое, если это будет сделано.

В этом случае не похоже, что метод "Dispose" в TableRow & TableCell делает что-либо, что препятствует их использованию в будущем. Вот почему у вас нет проблем.

Так как вы хотите, чтобы объекты использовались в будущем, вы не должны помещать их в блоки "using" вообще. Объект родительской страницы должен располагать элементами управления в конце жизненного цикла страницы.

Редактировать: я сделал тестовый серверный элемент управления и поместил точку останова в событие "Утилизация". Вот трассировка стека, которая показывает расположение вызовов.Net для вас. Вы можете использовать Reflector, чтобы посмотреть на код более подробно.

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)
Другие вопросы по тегам