protected ObjectReflectionMessagePackSerializer(Type type, SerializationContext context, SerializingMember[] members) : base(type, (context ?? SerializationContext.Default).CompatibilityOptions.PackerCompatibilityOptions) { if (type.GetIsAbstract() || type.GetIsInterface()) { throw SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractType(type); } this._createInstance = () => Activator.CreateInstance(type); //Expression.Lambda<Func<T>>( // typeof(T).GetIsValueType() // ? Expression.Default(typeof(T)) as Expression // : Expression.New(typeof(T).GetConstructor(ReflectionAbstractions.EmptyTypes)) // ).Compile(); var isPackable = typeof(IPackable).IsAssignableFrom(type); var isUnpackable = typeof(IUnpackable).IsAssignableFrom(type); if (isPackable && isUnpackable) { this._memberSerializers = null; this._indexMap = null; this._isCollection = null; this._nilImplications = null; this._memberNames = null; } else { this._memberSerializers = members.Select( m => m.Member == null ? NullSerializer.Instance : context.GetSerializer(m.Member.GetMemberValueType())).ToArray ( ); this._indexMap = members .Select((m, i) => new KeyValuePair<SerializingMember, int>(m, i)) .Where(kv => kv.Key.Member != null) .ToDictionary(kv => kv.Key.Contract.Name, kv => kv.Value); this._isCollection = members.Select( m => m.Member == null ? CollectionTraits.NotCollection : m.Member.GetMemberValueType().GetCollectionTraits()). Select(t => t.CollectionType != CollectionKind.NotCollection).ToArray(); // NilImplication validity check foreach (var member in members) { switch (member.Contract.NilImplication) { case NilImplication.Null: { if (member.Member.GetMemberValueType().GetIsValueType() && Nullable.GetUnderlyingType(member.Member.GetMemberValueType()) == null) { throw SerializationExceptions.NewValueTypeCannotBeNull( member.Contract.Name, member.Member.GetMemberValueType(), member.Member.DeclaringType ); } if (!member.Member.CanSetValue()) { throw SerializationExceptions.NewReadOnlyMemberItemsMustNotBeNull(member.Contract.Name); } break; } } } this._nilImplications = members.Select(m => m.Contract.NilImplication).ToArray(); this._memberNames = members.Select(m => m.Contract.Name).ToArray(); } if (isPackable) { this._packToMessage = (target, packer, packingOptions) => { ((IPackable)target).PackToMessage(packer, packingOptions); //typeof(T).GetInterfaceMap(typeof(IPackable)).TargetMethods.Single().Invoke(target, new object[] { packer, packingOptions }); }; this._memberGetters = null; } else { this._packToMessage = null; this._memberGetters = members.Select<SerializingMember,Func<object,object>>( m => m.Member == null ? (target => null) : CreateMemberGetter(m)).ToArray(); } if (isUnpackable) { this._unpackFromMessage = delegate(ref object target, Unpacker value) { ((IUnpackable)target).UnpackFromMessage(value); }; this._memberSetters = null; } else { this._unpackFromMessage = null; this._memberSetters = members.Select( m => m.Member == null ? delegate(ref object target, object memberValue) { } : m.Member.CanSetValue() ? CreateMemberSetter(m) : UnpackHelpers.IsReadOnlyAppendableCollectionMember(m.Member) ? default(MemberSetter) : ThrowGetOnlyMemberIsInvalid(m.Member) ).ToArray(); } }