void ReadGetOnlyCollection(CollectionDataContract collectionContract) { Type type = collectionContract.UnderlyingType; Type itemType = collectionContract.ItemType; bool isArray = (collectionContract.Kind == CollectionKind.Array); string itemName = collectionContract.ItemName; string itemNs = collectionContract.StableName.Namespace; objectLocal = context.GetCollectionMember(); //check that items are actually going to be deserialized into the collection if (IsStartElement(this.itemName, this.itemNamespace)) { if (objectLocal == null) { XmlObjectSerializerReadContext.ThrowNullValueReturnedForGetOnlyCollectionException(type); } else { int size = 0; if (isArray) { size = ((Array)objectLocal).Length; } context.AddNewObject(objectLocal); for (int i = 0; i < int.MaxValue;) { if (IsStartElement(this.itemName, this.itemNamespace)) { context.IncrementItemCount(1); var value = ReadCollectionItem(collectionContract, itemType, itemName, itemNs); if (isArray) { if (size == i) { XmlObjectSerializerReadContext.ThrowArrayExceededSizeException(size, type); } else { ((Array)objectLocal).SetValue(value, i); } } else { StoreCollectionValue(objectLocal, itemType, value, collectionContract); } } else if (IsEndElement()) { break; } else { HandleUnexpectedItemInCollection(ref i); } } context.CheckEndOfArray(xmlReader, size, this.itemName, this.itemNamespace); } } }
private CollectionSetItemDelegate GetCollectionSetItemDelegate <T>(CollectionDataContract collectionContract, object resultCollectionObject, bool isReadOnlyCollection) { if (isReadOnlyCollection && collectionContract.Kind == CollectionKind.Array) { int arraySize = ((Array)resultCollectionObject).Length; return((resultCollection, collectionItem, index) => { if (index == arraySize) { XmlObjectSerializerReadContext.ThrowArrayExceededSizeException(arraySize, collectionContract.UnderlyingType); } ((T[])resultCollection)[index] = (T)collectionItem; return resultCollection; }); } else if (!isReadOnlyCollection && IsArrayLikeCollection(collectionContract)) { return((resultCollection, collectionItem, index) => { resultCollection = XmlObjectSerializerReadContext.EnsureArraySize((T[])resultCollection, index); ((T[])resultCollection)[index] = (T)collectionItem; return resultCollection; }); } else if (collectionContract.Kind == CollectionKind.GenericDictionary || collectionContract.Kind == CollectionKind.Dictionary) { Type keyType = collectionContract.ItemType.GenericTypeArguments[0]; Type valueType = collectionContract.ItemType.GenericTypeArguments[1]; Func <object, object> objectToKeyValuePairGetKey = (Func <object, object>)s_objectToKeyValuePairGetKey.MakeGenericMethod(keyType, valueType).CreateDelegate(typeof(Func <object, object>)); Func <object, object> objectToKeyValuePairGetValue = (Func <object, object>)s_objectToKeyValuePairGetValue.MakeGenericMethod(keyType, valueType).CreateDelegate(typeof(Func <object, object>)); if (collectionContract.Kind == CollectionKind.GenericDictionary) { return((resultCollection, collectionItem, index) => { object key = objectToKeyValuePairGetKey(collectionItem); object value = objectToKeyValuePairGetValue(collectionItem); collectionContract.AddMethod.Invoke(resultCollection, new object[] { key, value }); return resultCollection; }); } else { return((resultCollection, collectionItem, index) => { object key = objectToKeyValuePairGetKey(collectionItem); object value = objectToKeyValuePairGetValue(collectionItem); IDictionary dict = (IDictionary)resultCollection; dict.Add(key, value); return resultCollection; }); } } else { Type collectionType = resultCollectionObject.GetType(); Type genericCollectionType = typeof(ICollection <T>); Type typeIList = Globals.TypeOfIList; if (genericCollectionType.IsAssignableFrom(collectionType)) { return((resultCollection, collectionItem, index) => { ((ICollection <T>)resultCollection).Add((T)collectionItem); return resultCollection; }); } else if (typeIList.IsAssignableFrom(collectionType)) { return((resultCollection, collectionItem, index) => { ((IList)resultCollection).Add(collectionItem); return resultCollection; }); } else { MethodInfo addMethod = collectionContract.AddMethod; if (addMethod == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.Format(SR.CollectionMustHaveAddMethod, DataContract.GetClrTypeFullName(collectionContract.UnderlyingType)))); } return((resultCollection, collectionItem, index) => { addMethod.Invoke(resultCollection, new object[] { collectionItem }); return resultCollection; }); } } }