8 10 2007
We recently implemented some changes in the software development methodology used at our company and quite by chance encountered an interesting .Net 2.0 problem. Namely, when an object array inherited from the same base class is cast on a base class and submitted to the data binder, the latter gets confused. The array contained objects from different classes but all these classes had one and the same base class.
After some investigation into the problem we realised the following sad fact. When data are bound to GridView, for example, then it is assumed that all objects have been created based on one and the same class. It means that in case of an array from an abstract class Animal, containing objects from classes Cat and Dog, we’ll get an error. GridView takes the first object from the array, studies it and assumes all other objects in the array to be of the same type.
From the viewpoint of the object-oriented world this means we are in quite a mess. Until we are dealing with ADO.NET data objects, everything is fine. DataTable and DataView contain DataRow and DataRowView collections, respectively, and this means GridView always gets objects of the same type. When moving on to specific objects, however, GridView and also other controllers associated with data can no longer manage.
Still, we found a temporary solution to this problem. Namely Sean M. Foy has written a class named DefensiveDatasource that helps GridView and others with the same trouble to understand the aforementioned arrays and collections. Using DefensiveDatasource in code is not complicated.
public class MyControl : Control
public void Page_Load(object sender, EventArgs e)
// Let's ask all the animals we have.
// For every animal there is class that inherits from Animal.
IList animals = Mapper.List(typeof(Animal));
grid.DataSource = new DefensiveDatasource(animals, null);
I found also the following materials concerning the deeper nature and possible solutions of the problem:
- Polymorphic Databinding Solutions (Ayende Rahien)