/// <summary> /// Transforms the de-serialized value to a value that is ready to be assigned to target /// object. If the target object is a collection then the de-serialized value is /// transformed to a collection that has the same type as the target object. If the target /// object is an enumerable then the de-serialized value is transformed to an enumerable /// that has the same type as the target object. If the target object is an Array then the /// de-serialized value is transofrmed to an Array that has the same type as the target. /// The target collection/enumerable is found using the virtual GetTargetCollection and /// GetTargetEnumerable methods. By default these method create new instances of the /// the collection/enumerable. This behavior can be overridden. For example, the /// MemberFixup class overrides these methods to return the actual value of the member so /// that the items of the collection can be assigned dorectly to the member itself. /// </summary> protected object TransformValue(object target, object value) { if (value == null) { return(null); } object transformedValue = value; if (m_TargetType is LogicalCollection) { transformedValue = GetTargetCollection(target); if (null == transformedValue) { return(null); } TransformHelper.CopyArrayLikeToTargetArrayLike(transformedValue, value, ((LogicalCollection)m_TargetType).AddMethod); } else if (m_TargetType is LogicalEnumerable) { transformedValue = GetTargetEnumerable(target); if (null == transformedValue) { return(null); } TransformHelper.CopyArrayLikeToTargetArrayLike(transformedValue, value, ((LogicalEnumerable)m_TargetType).AddMethod); } else if (SerializationHelper.isLogicalArray(m_TargetType)) { if (!m_TargetType.Type.IsAssignableFrom(value.GetType())) { Array srcArray = value as Array; if (srcArray == null) { srcArray = TransformHelper.CreateArrayFromCollection(value); if (srcArray == null) { return(null); } } try { transformedValue = Array.CreateInstance(m_TargetType.Type.GetElementType(), srcArray.Length); Array.Copy(srcArray, (Array)transformedValue, srcArray.Length); } catch (InvalidCastException) { throw new InvalidCastException(SR.Format(SR.XmlS_XmlInvalidCast_2, srcArray.GetType().FullName, m_TargetType.Type.FullName)); } } } return(transformedValue); }
/// <summary> /// Returns true if the LogicalType represents a complex type /// (struct or reference type). /// </summary> /// <remarks> /// Specifically a type that is not Nullable<T>, not a logical array, /// not a primitive, not an enum, and not a QName. /// </remarks> private bool isComplexObjectValue(LogicalType type) { if (!type.IsNullableType && !SerializationHelper.isLogicalArray(type) && !SerializationHelper.IsSerializationPrimitive(type.Type) && !type.Type.GetTypeInfo().IsEnum&& type.CustomSerializer != CustomSerializerType.QName && !SerializationHelper.isBuiltInBinary(type)) { return(true); } return(false); }