[Ненависть] DbDataAdapter.Dispose

Привет всем.

Интересно, кроме меня еще кто-нибудь когда-нибудь (грязно) ругался по поводу реализации DbDataAdapter.Dispose(disposing)?

override protected void Dispose(bool disposing) { // V1.0.3300, MDAC 69629
 if (disposing) { // release mananged objects
  IDbDataAdapter pthis = (IDbDataAdapter) this; // must cast to interface to obtain correct value
  pthis.SelectCommand = null; 
  pthis.InsertCommand = null;
  pthis.UpdateCommand = null; 
  pthis.DeleteCommand = null; 
 }
 
 // release unmanaged objects 
 base.Dispose(disposing); // notify base classes
}

Казалось бы — безобидный код. Но здесь есть одно но — эти обнуления (pthis.xxx=null) вызывают виртуальные set-методы, переопределенные в (моем) производном классе. А объект этого производного класса уже перешел в состоянии «Я Disposed». И соответственно первый же pthis.SelectCommand=null выкидывает исключение ObjectDisposedException.

Так учит партия — выкидывать ObjectDisposedException при обращении к любому методу (кроме Dispose) «освобожденного» объекта.

Спрашивается — какого черта ты из Dispose вызываешь виртуальные методы?

Хочется взять и <censored> того, кто написал этот код.

—-
В этом DbDataAdapter вообще как-то через … голову построена установка/получение SelectCommand/InsertCommand/UpdateCommand/DeleteCommand. Прямо чувствуется как мечется мысль в башке создателя DbDataAdapter: «как, как мне замутить установку «правильных» команд в DbDataAdapter?». И погибает, убивая себя об стол, об который бился череп.

По этой причине производные классы (те же System.Data.OleDb.OleDbDataAdapter и System.Data.SqlClient.SqlDataAdapter) кладут на эту инфраструктуру и переопределяют её на своем уровне (заново наследуют IDbDataAdapter). Но DbDataAdapter.Dispose и туда гадит.

Хочу быть тупым, чтобы даже не сталкиваться с такими вещами.

Leave a Comment