private static PropertyDescriptorCollection GetListItemPropertiesByEnumerable(IEnumerable iEnumerable, PropertyDescriptor[] listAccessors, int startIndex) {
PropertyDescriptorCollection pdc = null;
object subList = null;
// Walk down the tree - first try and get the value
// This is tricky, because we can't do a standard GetValue - we need an instance of one of the
// items in the list.
//
// For example:
//
// Customer has a property Orders which is of type Order[]
//
// Customers is a Customer[] (this is the IList)
// Customers does not have the property "Orders" - Customer has that property
// So we need to get the value of Customers[0]
//
object instance = GetFirstItemByEnumerable(iEnumerable);
if (instance != null) {
// This calls GetValue(Customers[0], "Orders") - or Customers[0].Orders
// If this list is non-null, it is an instance of Orders (Order[]) for the first customer
subList = GetList(listAccessors[startIndex].GetValue(instance));
}
if (null == subList) {
// Can't get shape by Instance, try by Type
pdc = GetListItemPropertiesByType(listAccessors[startIndex].PropertyType, listAccessors, startIndex);
}
else {
// We have the Instance (e.g. Orders)
++startIndex;
IEnumerable ienumerableSubList = subList as IEnumerable;
if (ienumerableSubList != null) {
if (startIndex == listAccessors.Length) {
// Last one, so get the shape
pdc = GetListItemPropertiesByEnumerable(ienumerableSubList);
}
else {
// Looks like they want more (e.g. Customers.Orders.OrderDetails)
pdc = GetListItemPropertiesByEnumerable(ienumerableSubList, listAccessors, startIndex);
}
}
else {
// Not a list, so switch to a non-list based method of retrieving properties
pdc = GetListItemPropertiesByInstance(subList, listAccessors, startIndex);
}
}
return pdc;
}