Example #1
0
        public void Serialize(ref BssomWriter writer, ref BssomSerializeContext context, object value)
        {
            if (value == null)
            {
                writer.WriteNull();
                return;
            }

            Type realType = value.GetType();

            if (realType == typeof(object))
            {
                writer.WriteArray1BuildInType(BssomType.Map2);
                BssMapObjMarshal.WriteEmptyMapObject(ref writer);
                return;
            }

            object formatter = context.Option.FormatterResolver.GetFormatterWithVerify(realType);

            if (!SerializerDelegates.TryGetValue(realType, out SerializeMethod serializerDelegate))
            {
                Type formatterType         = typeof(IBssomFormatter <>).MakeGenericType(realType);
                ParameterExpression param0 = Expression.Parameter(typeof(object), "formatter");
                ParameterExpression param1 = Expression.Parameter(typeof(BssomWriter).MakeByRefType(), "writer");
                ParameterExpression param2 = Expression.Parameter(typeof(BssomSerializeContext).MakeByRefType(), "context");
                ParameterExpression param3 = Expression.Parameter(typeof(object), "value");

                MethodInfo serializeMethod = formatterType.GetRuntimeMethod(nameof(Serialize), new[] { typeof(BssomWriter).MakeByRefType(), typeof(BssomSerializeContext).MakeByRefType(), realType });

                MethodCallExpression body = Expression.Call(
                    Expression.Convert(param0, formatterType),
                    serializeMethod,
                    param1, param2,
                    realType.IsValueType ? Expression.Unbox(param3, realType) : Expression.Convert(param3, realType)
                    );

                serializerDelegate = Expression.Lambda <SerializeMethod>(body, param0, param1, param2, param3).Compile();
                SerializerDelegates.TryAdd(realType, serializerDelegate);
            }

            serializerDelegate(formatter, ref writer, ref context, value);
        }