Столкнулся со штукой, которая очень мне вынесла мозг.
Пример
class A
{
DataSet aDs;
void AFoo()
{
var b = new B();
b.BFoo();
aDs = b.bDs;
b.Dispose();
//для объекта DataSet уже выполнен Dispose,
//но мы продолжаем работать с ним,
///как ни в чём не бывало
var newrow = aDs.Tables[0].NewRow();
FillNewRow(newrow);
aDs.ows.Tables[0].Add(newrow);
}
}
class B : IDisposable
{
public DataSet bDs;
public void BFoo()
{
bDs?.Dispose();
bDs = new DataSet();
bDataAdapter.Fill(bDs);
}
// IDisposable Support
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
bDs?.Dispose();
}
disposedValue = true;
}
}
}
Создали объект B, который создал объект DataSet и сохранил в публичном поле. Скопировали ссылку из этого публичного поля и вызвали Dispose для объекта B, в котором внутри вызывается, Dispose и для DataSet тоже. Но продолжаем с ним (c DataSet) работать, как будто ничего не вызывали. Почему так происходит?
За объяснением далеко ходить не нужно - документация C#.
Смотрим на наследуемые типы и видим среди них MarshalByValueComponent, который реализует IDisposable:
[ComVisibleAttribute(true)]
[TypeConverterAttribute(typeof(ComponentConverter))]
public class MarshalByValueComponent : IComponent, IDisposable, IServiceProvider
При этом сам DataSet не переопределяет Dispose(), так что вызов этого метода ничего, по сути, не делает. При этом высвобождаются ресурсы модуля MarshalByValueComponent, но на DataSet это никак не влияет.
За более "официальным" ответом можно перейти на всю ту же документацию и посмотреть DataSet.Dispose:
Может показаться, что Dispose() вообще не нужно вызывать, на эту тему есть довольно занятное "чтиво".
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости