4 using System.Collections;
5 using System.Collections.Generic;
8 namespace SiliconStudio.Core.Reflection
15 private static readonly List<string> ListOfMembersToRemove =
new List<string> {
"Capacity",
"Count",
"IsReadOnly",
"IsFixedSize",
"IsSynchronized",
"SyncRoot" };
17 private readonly Func<object, bool> IsReadOnlyFunction;
18 private readonly Func<object, int> GetCollectionCountFunction;
19 private readonly Action<object, object> CollectionAddFunction;
20 private readonly Action<object, int, object> CollectionInsertFunction;
21 private readonly Action<object, int> CollectionRemoveAtFunction;
22 private readonly
bool hasIndexerSetter;
32 if (!IsCollection(type))
33 throw new ArgumentException(
"Expecting a type inheriting from System.Collections.ICollection",
"type");
36 var collectionType = type.GetInterface(typeof(
IEnumerable<>));
37 ElementType = (collectionType != null) ? collectionType.GetGenericArguments()[0] : typeof(
object);
38 Category = DescriptorCategory.Collection;
39 bool typeSupported =
false;
45 var add = itype.GetMethod(
"Add",
new[] {ElementType});
46 CollectionAddFunction = (obj, value) => add.Invoke(obj,
new[] {value});
47 var countMethod = itype.GetProperty(
"Count").GetGetMethod();
48 GetCollectionCountFunction = o => (int)countMethod.Invoke(o, null);
49 var isReadOnly = itype.GetProperty(
"IsReadOnly").GetGetMethod();
50 IsReadOnlyFunction = obj => (bool)isReadOnly.Invoke(obj, null);
54 itype = type.GetInterface(typeof(IList<>));
57 var insert = itype.GetMethod(
"Insert",
new[] { typeof(
int), ElementType });
58 CollectionInsertFunction = (obj, index, value) => insert.Invoke(obj,
new[] { index, value });
59 var removeAt = itype.GetMethod(
"RemoveAt",
new[] { typeof(
int) });
60 CollectionRemoveAtFunction = (obj, index) => removeAt.Invoke(obj,
new object[] { index });
63 if (!typeSupported && typeof(IList).IsAssignableFrom(type))
65 CollectionAddFunction = (obj, value) => ((IList)obj).Add(value);
66 CollectionInsertFunction = (obj, index, value) => ((IList)obj).Insert(index, value);
67 CollectionRemoveAtFunction = (obj, index) => ((IList)obj).RemoveAt(index);
68 GetCollectionCountFunction = o => ((IList)o).Count;
69 IsReadOnlyFunction = obj => ((IList)obj).IsReadOnly;
70 hasIndexerSetter =
true;
76 throw new ArgumentException(
"Type [{0}] is not supported as a modifiable collection".ToFormat(type),
"type");
84 public Type ElementType {
get;
private set; }
94 return CollectionAddFunction != null;
103 public bool HasInsert
107 return CollectionInsertFunction != null;
114 public bool HasRemoveAt
118 return CollectionRemoveAtFunction != null;
126 public bool HasIndexerSetter
130 return hasIndexerSetter;
141 if (list == null)
throw new ArgumentNullException(
"list");
142 if (!(index is
int))
throw new ArgumentException(
"The index must be an int.");
143 return GetValue(list, (
int)index);
153 if (list == null)
throw new ArgumentNullException(
"list");
154 var iList = (IList)list;
158 public void SetValue(
object list,
object index,
object value)
160 if (list == null)
throw new ArgumentNullException(
"list");
161 if (!(index is
int))
throw new ArgumentException(
"The index must be an int.");
162 SetValue(list, (
int)index, value);
165 public void SetValue(
object list,
int index,
object value)
167 if (list == null)
throw new ArgumentNullException(
"list");
168 var iList = (IList)list;
169 iList[index] = value;
177 public void Add(
object collection,
object value)
179 CollectionAddFunction(collection, value);
188 public void Insert(
object collection,
int index,
object value)
190 CollectionInsertFunction(collection, index, value);
200 CollectionRemoveAtFunction(collection, index);
210 return collection == null || IsReadOnlyFunction == null || IsReadOnlyFunction(collection);
220 return collection == null || GetCollectionCountFunction == null ? -1 : GetCollectionCountFunction(collection);
230 return !type.IsArray && (typeof(
ICollection).IsAssignableFrom(type) || type.HasInterface(typeof(
ICollection<>)) || typeof(IList).IsAssignableFrom(type));
242 return !IsCompilerGenerated && base.PrepareMember(member);
override bool PrepareMember(MemberDescriptorBase member)
Provides a descriptor for a System.Collections.ICollection.
A IMemberDescriptor for a PropertyInfo
void Add(object collection, object value)
Add to the collections of the same type than this descriptor.
int GetCollectionCount(object collection)
Determines the number of elements of a collection, -1 if it cannot determine the number of elements...
void RemoveAt(object collection, int index)
Remove item at the given index from the collections of the same type.
Default implementation of a ITypeDescriptor.
void Insert(object collection, int index, object value)
Insert to the collections of the same type than this descriptor.
CollectionDescriptor(ITypeDescriptorFactory factory, Type type)
Initializes a new instance of the CollectionDescriptor class.
void SetValue(object list, object index, object value)
object GetValue(object list, object index)
Returns the value matching the given index in the collection.
bool IsReadOnly(object collection)
Determines whether the specified collection is read only.
void SetValue(object list, int index, object value)
object GetValue(object list, int index)
Returns the value matching the given index in the collection.
static bool IsCollection(Type type)
Determines whether the specified type is collection.
Base class for IMemberDescriptor for a MemberInfo
A factory to create an instance of a ITypeDescriptor