[Ненависть] 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 и туда гадит.
Хочу быть тупым, чтобы даже не сталкиваться с такими вещами.