private static PropertyDescriptorCollection GetListItemPropertiesByEnumerable(IEnumerable enumerable) {
PropertyDescriptorCollection pdc = null;
Type targetType = enumerable.GetType();
if (typeof(Array).IsAssignableFrom(targetType)) {
pdc = TypeDescriptor.GetProperties(targetType.GetElementType(), BrowsableAttributeList);
}
else {
ITypedList typedListEnumerable = enumerable as ITypedList;
if (typedListEnumerable != null) {
pdc = typedListEnumerable.GetItemProperties(null);
}
else {
PropertyInfo indexer = GetTypedIndexer(targetType);
if (indexer != null && !typeof(ICustomTypeDescriptor).IsAssignableFrom(indexer.PropertyType)) {
Type type = indexer.PropertyType;
pdc = TypeDescriptor.GetProperties(type, BrowsableAttributeList);
// Reflection, and consequently TypeDescriptor would not return properties defined on the "base" interface,
// for example
// public interface IPerson {String FirstName { get; set; }}
// public interface ITeacher : IPerson {int ClassRoom { get; set; }}
// typeof (ITeacher).GetProperties() would return only the "ClassRoom" property
// DevDiv2 518025
// if (type.IsInterface) {
// Type[] interfaces = type.GetInterfaces();
// // initialize the list to an arbitrary length greater than pdc.Count
// List<PropertyDescriptor> merged = new List<PropertyDescriptor>(pdc.Count * 2 + 1);
// foreach (Type baseInterface in interfaces) {
// PropertyDescriptorCollection props = TypeDescriptor.GetProperties(baseInterface, BrowsableAttributeList);
// if (props != null) {
// foreach (PropertyDescriptor p in props) {
// merged.Add(p);
// }
// }
// }
// if (merged.Count != 0) {
// PropertyDescriptor[] props = new PropertyDescriptor[pdc.Count];
// pdc.CopyTo(props, 0);
// merged.AddRange(props);
// pdc = new PropertyDescriptorCollection(merged.ToArray());
// }
// }
}
}
}
// See if we were successful - if not, return the shape of the first
// item in the list
if (null == pdc) {
object instance = GetFirstItemByEnumerable(enumerable);
if (enumerable is string) {
pdc = TypeDescriptor.GetProperties(enumerable, BrowsableAttributeList);
}
else if (instance == null) {
pdc = new PropertyDescriptorCollection(null);
}
else {
pdc = TypeDescriptor.GetProperties(instance, BrowsableAttributeList);
if (!(enumerable is IList) && (pdc == null || pdc.Count == 0)) {
pdc = TypeDescriptor.GetProperties(enumerable, BrowsableAttributeList);
}
}
}
// Return results
return pdc;
}