Represents a cached type used during serialization by a DataContractBinaryPlistSerializer.
コード例 #1
0
        /// <summary>
        /// Gets the writable plist value of the given object identified by the specified type.
        /// </summary>
        /// <param name="type">The of the object.</param>
        /// <param name="obj">The object to get the plist value of.</param>
        /// <returns>The plist value of the given object.</returns>
        private object GetWritablePlistObject(Type type, object obj)
        {
            object result = null;

            if (obj != null)
            {
                if (typeof(IPlistSerializable).IsAssignableFrom(type))
                {
                    result = ((IPlistSerializable)obj).ToPlistDictionary();
                }
                else if (typeof(IDictionary).IsAssignableFrom(type))
                {
                    IDictionary dict = obj as IDictionary;
                    Dictionary <object, object> resultDict = new Dictionary <object, object>();

                    foreach (object key in dict.Keys)
                    {
                        object value = dict[key];
                        resultDict[this.GetWritablePlistObject(key.GetType(), key)] = this.GetWritablePlistObject(value.GetType(), value);
                    }

                    result = resultDict;
                }
                else if (type.IsCollection())
                {
                    IEnumerable   coll       = obj as IEnumerable;
                    List <object> resultColl = new List <object>();

                    foreach (object value in coll)
                    {
                        resultColl.Add(this.GetWritablePlistObject(value.GetType(), value));
                    }

                    result = resultColl;
                }
                else if (type.IsPrimitiveOrEnum())
                {
                    result = obj;
                }
                else
                {
                    if (!this.typeCache.ContainsKey(type))
                    {
                        this.typeCache[type] = new TypeCacheItem(type);
                    }

                    TypeCacheItem cache = this.typeCache[type];
                    Dictionary <string, object> resultDict = new Dictionary <string, object>();

                    for (int i = 0; i < cache.Fields.Count; i++)
                    {
                        FieldInfo           field  = cache.Fields[i];
                        DataMemberAttribute member = cache.FieldMembers[i];
                        object fieldValue          = field.GetValue(obj);

                        if (member.EmitDefaultValue || !field.FieldType.IsDefaultValue(fieldValue))
                        {
                            resultDict[member.Name] = this.GetWritablePlistObject(field.FieldType, fieldValue);
                        }
                    }

                    for (int i = 0; i < cache.Properties.Count; i++)
                    {
                        PropertyInfo        property = cache.Properties[i];
                        DataMemberAttribute member   = cache.PropertyMembers[i];
                        object propertyValue         = property.GetValue(obj, null);

                        if (member.EmitDefaultValue || !property.PropertyType.IsDefaultValue(propertyValue))
                        {
                            resultDict[member.Name] = this.GetWritablePlistObject(property.PropertyType, propertyValue);
                        }
                    }

                    result = resultDict;
                }
            }

            return(result);
        }
コード例 #2
0
        /// <summary>
        /// Gets the readable plist value of the given object identified by the specified type.
        /// </summary>
        /// <param name="type">The type the object is expected to have after being de-serialized.</param>
        /// <param name="obj">The raw plist object value.</param>
        /// <returns>A readable plist object value.</returns>
        private object GetReadablePlistObject(Type type, object obj)
        {
            object      result    = null;
            IDictionary plistDict = obj as IDictionary;

            if (obj != null)
            {
                if (typeof(IPlistSerializable).IsAssignableFrom(type))
                {
                    if (plistDict != null)
                    {
                        IPlistSerializable serResult = (IPlistSerializable)Activator.CreateInstance(type);
                        serResult.FromPlistDictionary(plistDict);
                    }
                }
                else if (typeof(IDictionary).IsAssignableFrom(type))
                {
                    if (plistDict != null)
                    {
                        Type keyType = typeof(object), valueType = typeof(object);

                        if (type.IsGenericType)
                        {
                            Type[] args = type.GetGenericArguments();
                            keyType   = args[0];
                            valueType = args[1];
                        }

                        IDictionary dictResult = (IDictionary)(type.IsInterface ?
                                                               Activator.CreateInstance(typeof(Dictionary <,>).MakeGenericType(keyType, valueType)) :
                                                               Activator.CreateInstance(type));

                        foreach (object key in plistDict.Keys)
                        {
                            if (!type.IsGenericType)
                            {
                                keyType   = key.GetType();
                                valueType = plistDict[key] != null ? plistDict[key].GetType() : typeof(object);
                            }

                            dictResult[this.GetReadablePlistObject(keyType, key)] = this.GetReadablePlistObject(valueType, plistDict[key]);
                        }

                        result = dictResult;
                    }
                }
                else if (type.IsCollection())
                {
                    IEnumerable plistColl = obj as IEnumerable;

                    if (plistColl != null)
                    {
                        Type  valueType = typeof(object);
                        bool  isArray   = false;
                        IList listResult;

                        if (type.IsGenericType)
                        {
                            valueType = type.GetGenericArguments()[0];
                        }
                        else if (typeof(Array).IsAssignableFrom(type))
                        {
                            valueType = type.GetElementType();
                            isArray   = true;
                        }

                        if (isArray)
                        {
                            listResult = new ArrayList();
                        }
                        else
                        {
                            // TODO: The default DataContractSerializer uses an informal protocal requiring a method named "Add()"
                            // rather than requiring concrete collection types to implement IList.
                            listResult = (IList)(type.IsInterface ?
                                                 Activator.CreateInstance(typeof(List <>).MakeGenericType(valueType)) :
                                                 Activator.CreateInstance(type));
                        }

                        foreach (object value in plistColl)
                        {
                            listResult.Add(this.GetReadablePlistObject(valueType, value));
                        }

                        result = isArray ? ((ArrayList)listResult).ToArray() : listResult;
                    }
                }
                else if (type.IsPrimitiveOrEnum())
                {
                    result = obj;
                }
                else
                {
                    if (plistDict != null)
                    {
                        if (!this.typeCache.ContainsKey(type))
                        {
                            this.typeCache[type] = new TypeCacheItem(type);
                        }

                        TypeCacheItem cache = this.typeCache[type];
                        result = Activator.CreateInstance(type);

                        for (int i = 0; i < cache.Fields.Count; i++)
                        {
                            FieldInfo           field  = cache.Fields[i];
                            DataMemberAttribute member = cache.FieldMembers[i];

                            if (plistDict.Contains(member.Name))
                            {
                                field.SetValue(result, this.GetReadablePlistObject(field.FieldType, plistDict[member.Name]));
                            }
                        }

                        for (int i = 0; i < cache.Properties.Count; i++)
                        {
                            PropertyInfo        property = cache.Properties[i];
                            DataMemberAttribute member   = cache.PropertyMembers[i];

                            if (plistDict.Contains(member.Name))
                            {
                                property.SetValue(result, this.GetReadablePlistObject(property.PropertyType, plistDict[member.Name]), null);
                            }
                        }
                    }
                }
            }

            return(result);
        }