private void BuildCollectionCreateInstance(TContext context, Type concreteType, Type declaringType)
        {
            var createInstance = GetCollectionSerializerMethod("CreateInstance", declaringType);

            this.EmitMethodPrologue(context, CollectionSerializerMethod.CreateInstance, createInstance);
            TConstruct construct = null;

            try
            {
                var instanceType = concreteType ?? typeof(TObject);
                var collection   =
                    this.DeclareLocal(
                        context,
                        typeof(TObject),
                        "collection"
                        );
                var ctor          = UnpackHelpers.GetCollectionConstructor(instanceType);
                var ctorArguments = this.DetermineCollectionConstructorArguments(context, ctor);
                construct =
                    this.EmitSequentialStatements(
                        context,
                        typeof(TObject),
                        collection,
                        this.EmitStoreVariableStatement(
                            context,
                            collection,
                            this.EmitCreateNewObjectExpression(
                                context,
                                collection,
                                ctor,
                                ctorArguments
                                )
                            ),
                        this.EmitRetrunStatement(
                            context,
                            this.EmitLoadVariableExpression(context, collection)
                            )
                        );
            }
            finally
            {
                this.EmitMethodEpilogue(context, CollectionSerializerMethod.CreateInstance, construct);
            }
        }
        private void BuildCollectionCreateInstance(TContext context, Type concreteType)
        {
            context.BeginMethodOverride(MethodName.CreateInstance);

            var instanceType = concreteType ?? this.TargetType;
            var collection   =
                this.DeclareLocal(
                    context,
                    this.TargetType,
                    "collection"
                    );
            var ctor          = UnpackHelpers.GetCollectionConstructor(instanceType);
            var ctorArguments = this.DetermineCollectionConstructorArguments(context, ctor);

            context.EndMethodOverride(
                MethodName.CreateInstance,
                this.EmitSequentialStatements(
                    context,
                    this.TargetType,
                    collection,
                    this.EmitStoreVariableStatement(
                        context,
                        collection,
                        this.EmitCreateNewObjectExpression(
                            context,
                            collection,
                            ctor,
                            ctorArguments
                            )
                        ),
                    this.EmitRetrunStatement(
                        context,
                        this.EmitLoadVariableExpression(context, collection)
                        )
                    )
                );
        }
예제 #3
0
        public static Func <int, object> CreateCollectionInstanceFactory(Type abstractType, Type targetType, Type comparisonType)
#endif // !UNITY
        {
            var constructor = UnpackHelpers.GetCollectionConstructor(targetType);
            var parameters = constructor.GetParameters();

            switch (parameters.Length)
            {
            case 0:
            {
                return(_ =>
#if !UNITY
                       (T)
#endif // !UNITY
                       constructor.InvokePreservingExceptionType());
            }

            case 1:
            {
                if (parameters[0].ParameterType == typeof(int))
                {
                    return(capacity =>
#if !UNITY
                           (T)
#endif // !UNITY
                           constructor.InvokePreservingExceptionType(capacity));
                }
                else if (UnpackHelpers.IsIEqualityComparer(parameters[0].ParameterType))
                {
                    var comparer =
#if !UNITY
                        EqualityComparer <TKey> .Default;
#else
                        UnpackHelpers.GetEqualityComparer(comparisonType);
#endif // !UNITY
                    return(_ =>
#if !UNITY
                           (T)
#endif // !UNITY
                           constructor.InvokePreservingExceptionType(comparer));
                }

                break;
            }

            case 2:
            {
                var comparer =
#if !UNITY
                    EqualityComparer <TKey> .Default;
#else
                    UnpackHelpers.GetEqualityComparer(comparisonType);
#endif // !UNITY
                if (parameters[0].ParameterType == typeof(int) &&
                    UnpackHelpers.IsIEqualityComparer(parameters[1].ParameterType))
                {
                    return(capacity =>
#if !UNITY
                           (T)
#endif // !UNITY
                           constructor.InvokePreservingExceptionType(capacity, comparer));
                }
                else if (UnpackHelpers.IsIEqualityComparer(parameters[0].ParameterType) &&
                         parameters[0].ParameterType == typeof(int))
                {
                    return(capacity =>
#if !UNITY
                           (T)
#endif // !UNITY
                           constructor.InvokePreservingExceptionType(comparer, capacity));
                }

                break;
            }
            }

            throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(
#if !UNITY
                      typeof(T)
#else
                      abstractType
#endif // !UNITY
                      );
        }
        private IEnumerable <TConstruct> EmitCollectionUnpackFromStatements(TContext context, Type instanceType, PolymorphismSchema schema, TConstruct collection)
        {
            /*
             * #if ARRAY
             *	if (!unpacker.IsArrayHeader)
             * #else
             *	if (!unpacker.IsMapHeader)
             * #endif
             *	{
             *		throw SerializationExceptions.NewIsNotArrayHeader();
             *	}
             *	int capacity = ITEMS_COUNT(unpacker);
             *	TCollection collection = new ...;
             * #if HAS_ADD_IN_TYPE
             *	this.UnpackToCore(unpacker, array);
             * #else // Add only exists in concrete type
             *  UNPACK_TO_SPECIFIED_COLLECTION
             * #endif
             *	return collection;
             */
            var ctor = UnpackHelpers.GetCollectionConstructor(instanceType);

            yield return
                (CollectionTraitsOfThis.CollectionType == CollectionKind.Array
                                        ? this.EmitCheckIsArrayHeaderExpression(context, context.Unpacker)
                                        : this.EmitCheckIsMapHeaderExpression(context, context.Unpacker));

            var itemsCount = this.DeclareLocal(context, typeof(int), "itemsCount");

            yield return(itemsCount);

            yield return
                (this.EmitStoreVariableStatement(
                     context,
                     itemsCount,
                     this.EmitGetItemsCountExpression(context, context.Unpacker)
                     ));

            yield return(collection);

            if (CollectionTraitsOfThis.CollectionType == CollectionKind.Array && CollectionTraitsOfThis.AddMethod == null)
            {
                // deserialize with concrete collection's UnpackTo.
                yield return
                    (this.EmitStoreVariableStatement(
                         context,
                         collection,
                         this.EmitCreateNewObjectExpression(
                             context,
                             collection,
                             ctor,
                             ctor.GetParameters().Length == 0
                                                                ? NoConstructs
                                                                : new[] { itemsCount }
                             )
                         ));

                yield return
                    (this.EmitForLoop(
                         context,
                         itemsCount,
                         flc =>
                         this.EmitUnpackToCollectionLoopBody(
                             context,
                             flc,
                             instanceType.GetCollectionTraits(),
                             context.Unpacker,
                             collection,
                             (schema ?? PolymorphismSchema.Default).ItemSchema
                             )
                         ));
            }
            else
            {
                // use generated AddItem override.
                yield return
                    (this.EmitUnpackCollectionWithUnpackToExpression(
                         context,
                         ctor,
                         itemsCount,
                         context.Unpacker,
                         collection
                         ));
            }

            yield return
                (this.EmitRetrunStatement(
                     context,
                     this.EmitLoadVariableExpression(context, collection)
                     ));
        }