На SO есть много вопросов по этому вопросу, но я не нашел тот, который охватывает то, что я конкретно должен понимать.Ссылка на объект за пределами используемого() блока
Один из моих разработчиков написал этот код:
//
// ValidationDataTable is a typed DataTable, generated by the Framework
ValidationDataTable validationTable;
using (ValidationTableAdapter adapter = new ValidationTableAdapter()) {
using (validationTable = adapter.GetData()) { }
}
datafeedValidators.Add(new CountryFieldValidator(validationTable.ToDictionary(key => key.CountryCode, value => value.CountryName)));
// Party on...
//
Моего понимание: validationTable были захоронены, но не мусор, когда он упоминается в последней строке коды - но все равно должен быть бросил ObjectDisposedException
на .ToDictionary()
вызов. Но этот код с радостью создает действующий словарь и продолжает работать.
У меня есть теории, но не могу найти ничего определенного, чтобы подтвердить или сбить любого из них. И код можно переписать дюжину способов избежать проблемы; это не проблема. Мне просто нужно знать, в чем разница в моем понимании.
Мои вопросы:
- Является ли этот код действует и ведет себя так, как надо?
- Если нет, то успех, который мы видим, просто дерьмо?
- Есть ли что-то конкретное о
DataTable
, что позволяет получить доступ после объекта расположен - аналогично тому, какGZipStream
класса требует, чтобы избавиться от объекта для очистки потока, и, следовательно, позволяет делать звонки.ToArray()
и.GetBuffer()
после того, как объект имеет были утилизированы? - ... Что на самом деле вызывает исключение ObjectDisposedException при вызове методов? Я всегда предполагал, что это происходит из самой платформы .NET.
.
ПОЯСНЕНИЯ:
Это .NET Framework вопрос. Консенсус в том, что мое понимание верное - самому DataTable придется выбросить ObjectDisposedException
. Кроме того, что это не так. Не где-нибудь в исходном коде DataTable, поэтому я спрашиваю. Я предположил, что структура обеспечит исключение ObjectDisposedException после его размещения, что, по-видимому, не так ... в отличие от GZipStream, который разрешает доступ только к двум методам после Dispose(), DGAF DataTable. Хорошо.
Так что позвольте мне перефразировать вопрос: есть ли что-то внутреннее в DataTable, которое будет бомбить нас, потому что разрешены вызовы на расположенную таблицу? Я могу предположить, что Microsoft не очистила что-либо внутренне, что все свойства и значения будут там, нетронутыми, до тех пор, пока объект находится в области видимости - это просто не похоже на безопасное предположение. Этот код уходит независимо - я просто хотел понять, была ли умышленная причина, по которой Microsoft разрешает доступ к DataTable после Dispose()
, или это был надзор, а не забота и т. Д.
Также, если вы опротете вопрос или сделаете голосование чтобы закрыть его, пожалуйста, оставьте комментарий почему.
5. Если этот код заставляет членов команды делать двойной прием и нелегко понять (настроение, с которым я согласен), тогда его следует изменить в любом случае, если только по какой-либо причине, кроме поддержки команды. И этот разработчик должен приложить больше усилий для поддержки и меньше усилий, чтобы быть умным. Полностью пустые блоки кода должны быть красным флагом для любого, кто пишет код. – David
Да, это так. К сожалению, я не уверен, что он настолько умный, что это недостаток понимания со стороны разработчиков. Также может быть усталой ошибкой: P –
Согласен с @David. Пустой блок обычно означает, что вы делаете это неправильно. Краткие ответы: 1. возможно, 2. возможно, нет, 3. да - 'DataTable' на самом деле ничего не делает *, когда он расположен. Это источник некоторого разногласия, но, чтобы быть ясным, утилизация DataTable ничего не делает. 4. Это зависит от реализации конкретного класса. Ни структура, ни язык не заботятся об утилизации. Я бы посоветовал вам ознакомиться с одноразовым рисунком. –