/// <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); }
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); }