示例#1
0
        public TypeBuilder DefineCollectionFormatterType(Type type, Type elementType)
        {
            VerifyTypeIsPublic(type);

            string pre = "Array2.";

            if (Array1FormatterHelper.IsArray1Type(elementType))
            {
                pre = "Array1.";
            }

            Type        formatterType = typeof(IBssomFormatter <>).MakeGenericType(type);
            TypeBuilder typeBuilder   = DefineType("Bssom.Formatters." + pre + SubtractFullNameRegex.Replace(type.FullName, string.Empty).Replace(".", "_") + "Formatter" + Interlocked.Increment(ref nameSequence), TypeAttributes.NotPublic | TypeAttributes.Sealed, null, new[] { formatterType });

            return(typeBuilder);
        }
示例#2
0
        public static TypeInfo BuildICollectionImplementationType(DynamicFormatterAssembly assembly, Type type, ConstructorInfo constructor,
                                                                  Type itemType,
                                                                  bool isImplGenerIList, bool IsImplIList, bool isImplGenerICollec, bool isImplIReadOnlyList)
        {
            TypeBuilder typeBuilder = assembly.DefineFormatterType(type);

            MethodBuilder sizeMethod      = TypeBuildHelper.DefineSizeMethod(typeBuilder, type);
            MethodBuilder serializeMethod = TypeBuildHelper.DefineSerializeMethod(typeBuilder, type);

            if (itemType == typeof(object))
            {
                //itemType is Object, Array2
                if (IsImplIList)
                {
                    TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIList), BindingFlags.Public | BindingFlags.Static));
                }
                else
                {
                    TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIEnumerable), BindingFlags.Public | BindingFlags.Static));
                }

                TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeIEnumerable), BindingFlags.Public | BindingFlags.Static));
            }
            else
            {
                if (Array1FormatterHelper.IsArray1Type(itemType))
                {
                    //Array1
                    TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SerializeIEnumerable), new Type[] { typeof(BssomWriter).MakeByRefType(), typeof(BssomSerializeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(itemType) }));

                    TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SizeIEnumerable), new Type[] { typeof(BssomSizeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(itemType) }));
                }
                else
                {
                    if (isImplGenerIList || isImplIReadOnlyList)
                    {
                        TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenerIList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(itemType));
                    }
                    else
                    {
                        TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(itemType));
                    }

                    TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(itemType));
                }
            }

            MethodBuilder deserializeMethod = TypeBuildHelper.DefineDeserializeMethod(typeBuilder, type);

            ParameterInfo[] args = constructor.GetParameters();
            if (args.Length == 1 && args[0].ParameterType != typeof(int))
            {
                //new T(IEnumerable t)
                Type       dynamicCacheType = typeof(CollectionDynamicDelegateCache <>).MakeGenericType(type);
                MethodInfo methodinfo       = dynamicCacheType.GetMethod(nameof(CollectionDynamicDelegateCache <int> .GenerateInjectCtor));
                methodinfo.Invoke(null, new object[] { constructor, args[0].ParameterType });
                TypeBuildHelper.CallDeserializeDelegate(deserializeMethod, type, dynamicCacheType.GetField(nameof(CollectionDynamicDelegateCache <int> .Deserialize), BindingFlags.Public | BindingFlags.Static));
            }
            else
            {
                if (itemType == typeof(DateTime))//DateTime需要特殊处理,因为要处理Standrand和Native
                {
                    Type       dtCollBuilder = typeof(DateTimeCollectionDeserializeBuilder <>).MakeGenericType(type);
                    MethodInfo methodinfo    = dtCollBuilder.GetMethod(nameof(DateTimeCollectionDeserializeBuilder <ICollection <DateTime> > .ConstructorInit));
                    methodinfo.Invoke(null, new object[] { constructor });

                    TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, dtCollBuilder.GetMethod(nameof(DateTimeCollectionDeserializeBuilder <ICollection <DateTime> > .Deserialize)));
                }
                else
                {
                    Type dynamicCacheType = typeof(CollectionDynamicDelegateCache <>).MakeGenericType(type);
                    if (args.Length == 0)
                    {
                        MethodInfo methodinfo = dynamicCacheType.GetMethod(nameof(CollectionDynamicDelegateCache <int> .GenerateDeserializeWithEmptyCtor));
                        methodinfo.Invoke(null, new object[] { constructor, isImplGenerICollec, itemType });
                    }
                    else
                    {
                        DEBUG.Assert(args.Length == 1 && args[0].ParameterType == typeof(int));

                        MethodInfo methodinfo = dynamicCacheType.GetMethod(nameof(CollectionDynamicDelegateCache <int> .GenerateDeserializeWithCapacityCtor));
                        methodinfo.Invoke(null, new object[] { constructor, isImplGenerICollec, itemType });
                    }
                    TypeBuildHelper.CallDeserializeDelegate(deserializeMethod, type, dynamicCacheType.GetField(nameof(CollectionDynamicDelegateCache <int> .Deserialize), BindingFlags.Public | BindingFlags.Static));
                }
            }
            return(typeBuilder.CreateTypeInfo());
        }
示例#3
0
        public static TypeInfo BuildICollectionInterfaceType(DynamicFormatterAssembly assembly, Type type, Type elementType)
        {
            TypeBuilder typeBuilder = assembly.DefineCollectionFormatterType(type, elementType);

            MethodBuilder serializeMethod   = TypeBuildHelper.DefineSerializeMethod(typeBuilder, type);
            MethodBuilder deserializeMethod = TypeBuildHelper.DefineDeserializeMethod(typeBuilder, type);
            MethodBuilder sizeMethod        = TypeBuildHelper.DefineSizeMethod(typeBuilder, type);

            if (type.IsGenericType == false)
            {
                DEBUG.Assert(type == typeof(IEnumerable) || type == typeof(IList) || type == typeof(ICollection));
                //itemType is Object, Array2
                if (type == typeof(IList))
                {
                    TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIList), BindingFlags.Public | BindingFlags.Static));
                }
                else
                {
                    TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeIEnumerable), BindingFlags.Public | BindingFlags.Static));
                }

                TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.DeserializeList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(typeof(object)));

                TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeIEnumerable), BindingFlags.Public | BindingFlags.Static));
            }
            else
            {
                Type genericTypeDefine = type.GetGenericTypeDefinition();
                DEBUG.Assert(genericTypeDefine == typeof(IEnumerable <>) || genericTypeDefine == typeof(IList <>) || genericTypeDefine == typeof(ICollection <>) || genericTypeDefine == typeof(ISet <>) || genericTypeDefine == typeof(IReadOnlyList <>) || genericTypeDefine == typeof(IReadOnlyCollection <>));

                if (Array1FormatterHelper.IsArray1Type(elementType))
                {
                    //Array1
                    TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SerializeIEnumerable), new Type[] { typeof(BssomWriter).MakeByRefType(), typeof(BssomSerializeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(elementType) }));

                    if (genericTypeDefine == typeof(ISet <>))
                    {
                        TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array1FormatterHelper).GetMethod(Array1FormatterHelper.DeserializeSetPrefix + elementType.Name, BindingFlags.Public | BindingFlags.Static));
                    }
                    else
                    {
                        Type       listFormatterType = Array1ResolverGetFormatterHelper.GetListFormatterType(elementType);
                        FieldInfo  field             = listFormatterType.GetField(nameof(DateTimeListFormatter.Instance), BindingFlags.Static | BindingFlags.Public);
                        MethodInfo method            = listFormatterType.GetMethod(nameof(DateTimeListFormatter.Deserialize));
                        TypeBuildHelper.CallOneStaticFieldMethodInDeserialize(deserializeMethod, field, method);
                    }

                    TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array1FormatterHelper).GetMethod(nameof(Array1FormatterHelper.SizeIEnumerable), new Type[] { typeof(BssomSizeContext).MakeByRefType(), typeof(IEnumerable <>).MakeGenericType(elementType) }));
                }
                else
                {
                    if (genericTypeDefine == typeof(IList <>) || genericTypeDefine == typeof(IReadOnlyList <>))
                    {
                        TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenerIList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType));
                    }
                    else
                    {
                        TypeBuildHelper.CallOneMethodInSerialize(serializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SerializeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType));
                    }

                    if (genericTypeDefine == typeof(ISet <>))
                    {
                        TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.DeserializeSet), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType));
                    }
                    else
                    {
                        TypeBuildHelper.CallOneMethodInDeserialize(deserializeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.DeserializeList), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType));
                    }

                    TypeBuildHelper.CallOneMethodInSize(sizeMethod, typeof(Array2FormatterHelper).GetMethod(nameof(Array2FormatterHelper.SizeGenericIEnumerable), BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType));
                }
            }

            return(typeBuilder.CreateTypeInfo());
        }