void ReadCollection(CollectionDataContract collectionContract) { Type type = collectionContract.UnderlyingType; Type itemType = collectionContract.ItemType; bool isArray = (collectionContract.Kind == CollectionKind.Array); ConstructorInfo constructor = collectionContract.Constructor; if (type.IsInterface) { switch (collectionContract.Kind) { case CollectionKind.GenericDictionary: type = Globals.TypeOfDictionaryGeneric.MakeGenericType(itemType.GetGenericArguments()); constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null); break; case CollectionKind.Dictionary: type = Globals.TypeOfHashtable; constructor = XmlFormatGeneratorStatics.HashtableCtor; break; case CollectionKind.Collection: case CollectionKind.GenericCollection: case CollectionKind.Enumerable: case CollectionKind.GenericEnumerable: case CollectionKind.List: case CollectionKind.GenericList: type = itemType.MakeArrayType(); isArray = true; break; } } string itemName = collectionContract.ItemName; string itemNs = collectionContract.StableName.Namespace; if (!isArray) { if (type.IsValueType) { // FIXME: this is not what the original code does. objectLocal = FormatterServices.GetUninitializedObject(type); } else { objectLocal = constructor.Invoke(new object [0]); context.AddNewObject(objectLocal); } } int size = context.GetArraySize(); string objectId = context.GetObjectId(); bool canReadPrimitiveArray = false, readResult = false; if (isArray && TryReadPrimitiveArray(type, itemType, size, out readResult)) { canReadPrimitiveArray = true; } if (!readResult) { if (size == -1) { object growingCollection = null; if (isArray) { growingCollection = Array.CreateInstance(itemType, 32); } int i = 0; // FIXME: I cannot find i++ part, but without that it won't work as expected. for (; i < int.MaxValue; i++) { if (IsStartElement(this.itemName, this.itemNamespace)) { context.IncrementItemCount(1); object value = ReadCollectionItem(collectionContract, itemType, itemName, itemNs); if (isArray) { MethodInfo ensureArraySizeMethod = XmlFormatGeneratorStatics.EnsureArraySizeMethod.MakeGenericMethod(itemType); growingCollection = ensureArraySizeMethod.Invoke(null, new object [] { growingCollection, i }); ((Array)growingCollection).SetValue(value, i); } else { StoreCollectionValue(objectLocal, itemType, value, collectionContract); } } else if (IsEndElement()) { break; } else { HandleUnexpectedItemInCollection(ref i); } } if (isArray) { MethodInfo trimArraySizeMethod = XmlFormatGeneratorStatics.TrimArraySizeMethod.MakeGenericMethod(itemType); objectLocal = trimArraySizeMethod.Invoke(null, new object [] { growingCollection, i }); context.AddNewObjectWithId(objectId, objectLocal); } } else { context.IncrementItemCount(size); if (isArray) { objectLocal = Array.CreateInstance(itemType, size); context.AddNewObject(objectLocal); } // FIXME: I cannot find j++ part, but without that it won't work as expected. for (int j = 0; j < size; j++) { if (IsStartElement(this.itemName, this.itemNamespace)) { var itemValue = ReadCollectionItem(collectionContract, itemType, itemName, itemNs); if (isArray) { ((Array)objectLocal).SetValue(itemValue, j); } else { StoreCollectionValue(objectLocal, itemType, itemValue, collectionContract); } } else { HandleUnexpectedItemInCollection(ref j); } } context.CheckEndOfArray(xmlReader, size, this.itemName, this.itemNamespace); } } if (canReadPrimitiveArray) { context.AddNewObjectWithId(objectId, objectLocal); } }