コード例 #1
0
ファイル: ObjectWriter.cs プロジェクト: yufengfei/Aoite
        /// <summary>
        /// 序列化指定的对象。
        /// </summary>
        /// <param name="value">序列化的对象。</param>
        /// <param name="member">序列化的对象成员。</param>
        public void Serialize(object value, System.Reflection.MemberInfo member = null)
        {
            #region Null & DbNull & SuccessfullyResult

            if (value == null)
            {
                this.WriteNull();
                return;
            }
            if (value is DBNull)
            {
                this.WriteDBNull();
                return;
            }
            if (value is SuccessfullyResult)
            {
                this.WriteSuccessfullyResult();
                return;
            }

            #endregion

            #region ValueType

            if (value is ValueType)
            {
                if (value is Enum)
                {
                    value = Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType()), null);
                }

                if (value is Guid)
                {
                    this.WriteGuid((Guid)value);
                }
                else if (value is DateTime)
                {
                    this.WriteDateTime((DateTime)value);
                }
                else if (value is TimeSpan)
                {
                    this.WriteTimeSpan((TimeSpan)value);
                }
                else if (value is Boolean)
                {
                    this.WriteBoolean((Boolean)value);
                }
                else if (value is Byte)
                {
                    this.WriteByte((Byte)value);
                }
                else if (value is SByte)
                {
                    this.WriteSByte((SByte)value);
                }
                else if (value is Char)
                {
                    this.WriteChar((Char)value);
                }
                else if (value is Single)
                {
                    this.WriteSingle((Single)value);
                }
                else if (value is Double)
                {
                    this.WriteDouble((Double)value);
                }
                else if (value is Decimal)
                {
                    this.WriteDecimal((Decimal)value);
                }
                else if (value is Int16)
                {
                    this.WriteInt16((Int16)value);
                }
                else if (value is Int32)
                {
                    this.WriteInt32((Int32)value);
                }
                else if (value is Int64)
                {
                    this.WriteInt64((Int64)value);
                }
                else if (value is UInt16)
                {
                    this.WriteUInt16((UInt16)value);
                }
                else if (value is UInt32)
                {
                    this.WriteUInt32((UInt32)value);
                }
                else if (value is UInt64)
                {
                    this.WriteUInt64((UInt64)value);
                }
                else
                {
                    this.WriteValueTypeObject(value);
                }
                return;
            }

            #endregion

            if (this.TryWriteReference(value))
            {
                return;
            }

            #region Simple

            if (value is String)
            {
                this.WriteString((String)value);
                return;
            }

            if (value is StringBuilder)
            {
                this.WriteStringBuilder((StringBuilder)value);
                return;
            }
            if (value is Type)
            {
                this.WriteType((Type)value);
                return;
            }

            #endregion

            #region Array

            if (value is Array)
            {
                if (value is String[])
                {
                    this.WriteStringArray((String[])value);
                }
                else if (value is Guid[])
                {
                    this.WriteGuidArray((Guid[])value);
                }
                else if (value is DateTime[])
                {
                    this.WriteDateTimeArray((DateTime[])value);
                }
                else if (value is TimeSpan[])
                {
                    this.WriteTimeSpanArray((TimeSpan[])value);
                }
                else if (value is Boolean[])
                {
                    this.WriteBooleanArray((Boolean[])value);
                }
                else if (value is Byte[])
                {
                    this.WriteByteArray((Byte[])value);
                }
                else if (value is SByte[])
                {
                    this.WriteSByteArray((SByte[])value);
                }
                else if (value is Char[])
                {
                    this.WriteCharArray((Char[])value);
                }
                else if (value is Single[])
                {
                    this.WriteSingleArray((Single[])value);
                }
                else if (value is Double[])
                {
                    this.WriteDoubleArray((Double[])value);
                }
                else if (value is Decimal[])
                {
                    this.WriteDecimalArray((Decimal[])value);
                }
                else if (value is Int16[])
                {
                    this.WriteInt16Array((Int16[])value);
                }
                else if (value is Int32[])
                {
                    this.WriteInt32Array((Int32[])value);
                }
                else if (value is Int64[])
                {
                    this.WriteInt64Array((Int64[])value);
                }
                else if (value is UInt16[])
                {
                    this.WriteUInt16Array((UInt16[])value);
                }
                else if (value is UInt32[])
                {
                    this.WriteUInt32Array((UInt32[])value);
                }
                else if (value is UInt64[])
                {
                    this.WriteUInt64Array((UInt64[])value);
                }
                else if (value is StringBuilder[])
                {
                    this.WriteStringBuilderArray((StringBuilder[])value);
                }
                else if (value is Type[])
                {
                    this.WriteTypeArray((Type[])value);
                }
                else if (value.GetType() == Types.ObjectArray)
                {
                    this.WriteObjectArray((Object[])value);
                }
                else
                {
                    this.WriteArray(value as Array);
                }
                return;
            }

            #endregion

            var type = value.GetType();

            var customAttr = type.GetAttribute <SerializableUsageAttribute>()
                             ?? (member == null ? null : member.GetAttribute <SerializableUsageAttribute>())
                             ?? QuicklySerializer.CustomAttributes.TryGetValue(type);
            if (customAttr != null)
            {
                this.WriteCustom(value, customAttr.FormatterType);
                return;
            }

            #region Result & Generic

            if (type == Types.Result)
            {
                this.WriteResult((Result)value);
                return;
            }
            if (type == Types.HybridDictionary)
            {
                this.WriteHybridDictionary((System.Collections.Specialized.HybridDictionary)value);
                return;
            }
            if (type.IsGenericType)
            {
                var defineType = type.GetGenericTypeDefinition();
                if (Types.GResult == defineType)
                {
                    this.WriteGResult((Result)value, type);
                    return;
                }
                if (Types.GList == defineType)
                {
                    this.WriteGList((IList)value, type);
                    return;
                }
                if (Types.GConcurrentDictionary == defineType)
                {
                    this.WriteGConcurrentDictionary((IDictionary)value, type);
                    return;
                }
                if (Types.GDictionary == defineType)
                {
                    this.WriteGDictionary((IDictionary)value, type);
                    return;
                }
            }

            #endregion

            this.WriteObject(value, type);
        }
コード例 #2
0
        private void RegisterMember(Type type, System.Reflection.MemberInfo m, Type mType, Func <object, object> get, Action <object, object> set)
        {
            // struct that holds access method for property/field
            MemberInfo accessor = new MemberInfo();

            accessor.Type = mType;
            accessor.Get  = get;
            accessor.Set  = set;

            if (set != null) // writeable ?
            {
                accessor.SerializeMethod = YamlSerializeMethod.Assign;
            }
            else
            {
                accessor.SerializeMethod = YamlSerializeMethod.Never;
                if (mType.IsClass)
                {
                    accessor.SerializeMethod = YamlSerializeMethod.Content;
                }
            }
            var attr1 = m.GetAttribute <YamlSerializeAttribute>();

            if (attr1 != null)     // specified
            {
                if (set == null)   // read only member
                {
                    if (attr1.SerializeMethod == YamlSerializeMethod.Assign ||
                        (mType.IsValueType && accessor.SerializeMethod == YamlSerializeMethod.Content))
                    {
                        throw new ArgumentException("{0} {1} is not writeable by {2}."
                                                    .DoFormat(mType.FullName, m.Name, attr1.SerializeMethod.ToString()));
                    }
                }
                accessor.SerializeMethod = attr1.SerializeMethod;
            }
            if (accessor.SerializeMethod == YamlSerializeMethod.Never)
            {
                return; // no need to register
            }
            if (accessor.SerializeMethod == YamlSerializeMethod.Binary)
            {
                if (!mType.IsArray)
                {
                    throw new InvalidOperationException("{0} {1} of {2} is not an array. Can not be serialized as binary."
                                                        .DoFormat(mType.FullName, m.Name, type.FullName));
                }
                if (!TypeUtils.IsPureValueType(mType.GetElementType()))
                {
                    throw new InvalidOperationException(
                              "{0} is not a pure ValueType. {1} {2} of {3} can not serialize as binary."
                              .DoFormat(mType.GetElementType(), mType.FullName, m.Name, type.FullName));
                }
            }

            // ShouldSerialize
            //      YamlSerializeAttribute(Never) => false
            //      ShouldSerializeSomeProperty => call it
            //      DefaultValueAttribute(default) => compare to it
            //      otherwise => true
            var shouldSerialize = type.GetMethod("ShouldSerialize" + m.Name,
                                                 System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

            if (shouldSerialize != null && shouldSerialize.ReturnType == typeof(bool) && accessor.ShouldSeriealize == null)
            {
                accessor.ShouldSeriealize = obj => (bool)shouldSerialize.Invoke(obj, EmptyObjectArray);
            }
            var attr2 = m.GetAttribute <DefaultValueAttribute>();

            if (attr2 != null && accessor.ShouldSeriealize == null)
            {
                var defaultValue = attr2.Value;
                if (TypeUtils.IsNumeric(defaultValue) && defaultValue.GetType() != mType)
                {
                    defaultValue = TypeUtils.CastToNumericType(defaultValue, mType);
                }
                accessor.ShouldSeriealize = obj => !TypeUtils.AreEqual(defaultValue, accessor.Get(obj));
            }
            if (accessor.ShouldSeriealize == null)
            {
                accessor.ShouldSeriealize = obj => true;
            }

            Members.Add(m.Name, accessor);
        }