예제 #1
0
        FastSerialisationTypeConversionResult IFastSerialisationTypeConverter.GetDirectWriterIfPossible(Type sourceType, MemberSetterDetailsRetriever memberSetterDetailsRetriever)
        {
            if (sourceType == null)
            {
                throw new ArgumentNullException(nameof(sourceType));
            }
            if (memberSetterDetailsRetriever == null)
            {
                throw new ArgumentNullException(nameof(memberSetterDetailsRetriever));
            }

            if (!typeof(Type).IsAssignableFrom(sourceType))
            {
                return(null);
            }

            var sourceParameter = Expression.Parameter(sourceType, "source");
            var writerParameter = Expression.Parameter(typeof(BinarySerialisationWriter), "writer");

            return(FastSerialisationTypeConversionResult.ConvertTo(
                       sourceType,
                       typeof(string),
                       Expression.Lambda(
                           Expression.Call(
                               writerParameter,
                               _stringWriteMethod,
                               Expression.Property(sourceParameter, _assemblyQualifiedNameProperty)
                               ),
                           sourceParameter,
                           writerParameter
                           )
                       ));
        }
        FastSerialisationTypeConversionResult IFastSerialisationTypeConverter.GetDirectWriterIfPossible(Type sourceType, MemberSetterDetailsRetriever memberSetterDetailsRetriever)
        {
            if (sourceType == null)
            {
                throw new ArgumentNullException(nameof(sourceType));
            }
            if (memberSetterDetailsRetriever == null)
            {
                throw new ArgumentNullException(nameof(memberSetterDetailsRetriever));
            }

            if (!sourceType.IsGenericType)
            {
                return(null);
            }
            var genericTypeDefinition = sourceType.GetGenericTypeDefinition();

            if (genericTypeDefinition != typeof(IEqualityComparer <>))
            {
                return(null);
            }

            var comparedType = sourceType.GetGenericArguments()[0];

            if (_serialisationConverters.TryGetValue(comparedType, out var conversionResult))
            {
                return(conversionResult);                // This may be null if the memberSetterDetailsRetriever call below returned null earlier
            }
            var defaultComparerType       = typeof(DefaultEqualityComparer <>).MakeGenericType(comparedType);
            var defaultComparerTypeWriter = memberSetterDetailsRetriever(defaultComparerType);

            if (defaultComparerTypeWriter == null)
            {
                // Since the DefaultEqualityComparer class is so simple, I wouldn't expect memberSetterDetailsRetriever to return null but it's
                // possible and so it needs to be handled - the null will be added to the cache dictionary to avoid repeating this work later on
                conversionResult = null;
            }
            else
            {
                var writerParameter = Expression.Parameter(typeof(BinarySerialisationWriter), "writer");
                conversionResult = FastSerialisationTypeConversionResult.ConvertTo(
                    type: sourceType,
                    convertedToType: defaultComparerType,
                    memberSetter: Expression.Lambda(
                        Expression.Invoke(
                            defaultComparerTypeWriter.MemberSetter,
                            Expression.MakeMemberAccess(null, defaultComparerType.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static)),
                            writerParameter
                            ),
                        Expression.Parameter(sourceType, "source"),
                        writerParameter
                        )
                    );
            }
            return(_serialisationConverters.GetOrAdd(sourceType, conversionResult));
        }
        FastSerialisationTypeConversionResult IFastSerialisationTypeConverter.GetDirectWriterIfPossible(Type sourceType, MemberSetterDetailsRetriever memberSetterDetailsRetriever)
        {
            if (sourceType == null)
            {
                throw new ArgumentNullException(nameof(sourceType));
            }
            if (memberSetterDetailsRetriever == null)
            {
                throw new ArgumentNullException(nameof(memberSetterDetailsRetriever));
            }

            return((sourceType == typeof(SerializationInfo))
                                ? FastSerialisationTypeConversionResult.SetToDefault(sourceType)
                                : null);
        }
예제 #4
0
        FastSerialisationTypeConversionResult IFastSerialisationTypeConverter.GetDirectWriterIfPossible(Type sourceType, MemberSetterDetailsRetriever memberSetterDetailsRetriever)
        {
            if (sourceType == null)
            {
                throw new ArgumentNullException(nameof(sourceType));
            }
            if (memberSetterDetailsRetriever == null)
            {
                throw new ArgumentNullException(nameof(memberSetterDetailsRetriever));
            }

            var serialiser = TryToGetListSerialiserFromCache(sourceType);

            if (serialiser == null)
            {
                return(null);
            }

            var flattenedType       = typeof(FlattenedImmutableList <>).MakeGenericType(serialiser.ElementType);
            var flattenedTypeWriter = memberSetterDetailsRetriever(flattenedType);

            if (flattenedTypeWriter == null)
            {
                return(null);
            }

            var sourceParameter = Expression.Parameter(sourceType, "source");
            var writerParameter = Expression.Parameter(typeof(BinarySerialisationWriter), "writer");

            return(FastSerialisationTypeConversionResult.ConvertTo(
                       sourceType,
                       flattenedType,
                       Expression.Lambda(
                           Expression.Invoke(
                               flattenedTypeWriter.MemberSetter,
                               Expression.New(
                                   flattenedType.GetConstructor(new[] { serialiser.ElementType.MakeArrayType() }),
                                   GetToArrayCall(sourceParameter, sourceType, serialiser.ElementType)
                                   ),
                               writerParameter
                               ),
                           sourceParameter,
                           writerParameter
                           )
                       ));
        }