private object ReadCollectionProperty_InitializeCollection(PropertyInfo property, Type targetType, IReader reader) { object collection = null; if (reader.CanSet(property)) { if (property.PropertyType.IsArray) { collection = Activator.CreateInstance(typeof(List <>).MakeGenericType(targetType)); } else { collection = Activator.CreateInstance(property.PropertyType); } } else { if (reader.CanGet(property)) { collection = reader.Get(property); } if (collection == null) { throw new InvalidOperationException($"The value of the property {property.DeclaringType.FullName}.{property.Name} has no set accessor and is not initialized by default"); } } return(collection); }
private bool ReadCollectionProperty(XmlElement element, BXmlPropertyAttribute propertyAttribute, PropertyInfo property, IReader reader, Type targetType, BXmlElementAttribute elementAttribute1, BXmlSelectAttribute selectAttribute) { object collection = ReadCollectionProperty_InitializeCollection(property, targetType, reader); MethodInfo method = collection.GetType().GetMethod("Add", new Type[] { targetType }); if (method == null) { throw new InvalidOperationException($"The type of the property {property.DeclaringType.FullName}.{property.Name} has no Add({targetType.FullName}) method"); } var collectionElement = FindChildElement(element, propertyAttribute.Name); if (collectionElement == null) { return(false); } object[] parameters = new object[] { null }; Func <XmlElement, object> deserializer; if (elementAttribute1 != null) { deserializer = e => Deserialize(e, targetType); } else { deserializer = e => Deserialize(e, selectAttribute.Options); } foreach (XmlNode node in collectionElement.ChildNodes) { if (node is not XmlElement childElement) { continue; } parameters[0] = deserializer(childElement); method.Invoke(collection, parameters); } if (reader.CanSet(property)) { if (property.PropertyType.IsArray) { collection = collection.GetType().GetMethod("ToArray", new Type[] { }).Invoke(collection, Array.Empty <object>()); } reader.Set(property, collection); } return(true); }