private static Type GetListItemType(Type type)
 {
   Type type1;
   if (typeof (Array).IsAssignableFrom(type))
   {
     type1 = type.GetElementType();
   }
   else
   {
     PropertyInfo typedIndexer = DataRecordObjectView.GetTypedIndexer(type);
     type1 = !(typedIndexer != (PropertyInfo) null) ? type : typedIndexer.PropertyType;
   }
   return type1;
 }
        /// <summary>
        ///     Return a list suitable for data binding using the supplied query results.
        /// </summary>
        /// <typeparam name="TElement"> CLR type of query result elements declared by the caller. </typeparam>
        /// <param name="elementEdmTypeUsage"> The EDM type of the query results, used as the primary means of determining the CLR type of list returned by this method. </param>
        /// <param name="queryResults"> IEnumerable used to enumerate query results used to populate binding list. Must not be null. </param>
        /// <param name="objectContext">
        ///     <see cref="ObjectContext" /> associated with the query from which results were obtained. Must not be null.
        /// </param>
        /// <param name="forceReadOnly">
        ///     <b>True</b> to prevent modifications to the binding list built from the query result; otherwise <b>false</b> . Note that other conditions may prevent the binding list from being modified, so a value of <b>false</b> supplied for this parameter doesn't necessarily mean that the list will be writable.
        /// </param>
        /// <param name="singleEntitySet">
        ///     If the query results are composed of entities that only exist in a single
        ///     <see
        ///         cref="EntitySet" />
        ///     , the value of this parameter is the single EntitySet. Otherwise the value of this parameter should be null.
        /// </param>
        /// <returns>
        ///     <see cref="IBindingList" /> that is suitable for data binding.
        /// </returns>
        internal static IBindingList CreateViewForQuery <TElement>(
            TypeUsage elementEdmTypeUsage, IEnumerable <TElement> queryResults, ObjectContext objectContext, bool forceReadOnly,
            EntitySet singleEntitySet)
        {
            DebugCheck.NotNull(queryResults);
            DebugCheck.NotNull(objectContext);

            Type clrElementType         = null;
            var  ospaceElementTypeUsage = GetOSpaceTypeUsage(elementEdmTypeUsage, objectContext);

            // Map the O-Space EDM type to a CLR type.
            // If the mapping is unsuccessful, fallback to TElement type.
            if (ospaceElementTypeUsage == null)
            {
                clrElementType = typeof(TElement);
            }
            {
                clrElementType = GetClrType <TElement>(ospaceElementTypeUsage.EdmType);
            }

            IBindingList objectView;
            object       eventDataSource = objectContext.ObjectStateManager;

            // If the clrElementType matches the declared TElement type, optimize the construction of the ObjectView
            // by avoiding a reflection-based instantiation.
            if (clrElementType == typeof(TElement))
            {
                var viewData = new ObjectViewQueryResultData <TElement>(queryResults, objectContext, forceReadOnly, singleEntitySet);

                objectView = new ObjectView <TElement>(viewData, eventDataSource);
            }
            else if (clrElementType == null)
            {
                var viewData = new ObjectViewQueryResultData <DbDataRecord>(queryResults, objectContext, true, null);
                objectView = new DataRecordObjectView(viewData, eventDataSource, (RowType)ospaceElementTypeUsage.EdmType, typeof(TElement));
            }
            else
            {
                if (!typeof(TElement).IsAssignableFrom(clrElementType))
                {
                    throw EntityUtil.ValueInvalidCast(clrElementType, typeof(TElement));
                }

                // Use reflection to create an instance of the generic ObjectView and ObjectViewQueryResultData classes,
                // using clrElementType as the value of TElement generic type parameter for both classes.

                var objectViewDataType = _genericObjectViewQueryResultDataType.MakeGenericType(clrElementType);

                var viewDataConstructor = objectViewDataType.GetConstructor(
                    BindingFlags.Instance | BindingFlags.NonPublic,
                    null,
                    new[] { typeof(IEnumerable), typeof(ObjectContext), typeof(bool), typeof(EntitySet) },
                    null);

                Debug.Assert(
                    viewDataConstructor != null,
                    "ObjectViewQueryResultData constructor not found. Please ensure constructor signature is correct.");

                // Create ObjectViewQueryResultData instance
                var viewData = viewDataConstructor.Invoke(new object[] { queryResults, objectContext, forceReadOnly, singleEntitySet });

                // Create ObjectView instance
                objectView = CreateObjectView(clrElementType, objectViewDataType, viewData, eventDataSource);
            }

            return(objectView);
        }
 PropertyDescriptorCollection ITypedList.GetItemProperties(
   PropertyDescriptor[] listAccessors)
 {
   PropertyDescriptorCollection descriptorCollection;
   if (listAccessors == null || listAccessors.Length == 0)
   {
     descriptorCollection = this._propertyDescriptorsCache;
   }
   else
   {
     PropertyDescriptor listAccessor = listAccessors[listAccessors.Length - 1];
     FieldDescriptor fieldDescriptor = listAccessor as FieldDescriptor;
     descriptorCollection = fieldDescriptor == null || fieldDescriptor.EdmProperty == null || fieldDescriptor.EdmProperty.TypeUsage.EdmType.BuiltInTypeKind != BuiltInTypeKind.RowType ? TypeDescriptor.GetProperties(DataRecordObjectView.GetListItemType(listAccessor.PropertyType)) : MaterializedDataRecord.CreatePropertyDescriptorCollection((StructuralType) fieldDescriptor.EdmProperty.TypeUsage.EdmType, typeof (IDataRecord), true);
   }
   return descriptorCollection;
 }