Пример #1
0
        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;
                    });
                }
            }
        }