Пример #1
0
        internal static List <FieldInfo> GetOrderedFields(Type type, ImmutableSettings settings)
        {
            var mustUseReflectionToSetReadonly = FieldInfoModifier.MustUseReflectionToSetReadonly(settings);

            lock (_cacheLock)
            {
                ref var fields = ref _orderedCache.GetOrAddValueRef(new OrderedTypeCacheKey {
                    Type = type, Flattened = settings.FlattenClassHierarchy
                });
                if (fields == null)
                {
                    var unorderedFields = settings.FlattenClassHierarchy ? GetFlattenedFields(type) : GetFields(type);
                    if (mustUseReflectionToSetReadonly)
                    {
                        fields = unorderedFields.OrderBy(x => IsPrimitive(x.FieldType) ? 0 : 1)
                                 .ThenBy(x => x.IsInitOnly ? 0 : 1)
                                 .ThenBy(x => x.FieldType == typeof(string) ? 0 : 1)
                                 .ThenBy(x => x.Name).ToList();
                    }
                    else
                    {
                        fields = unorderedFields.OrderBy(x => IsPrimitive(x.FieldType) ? 0 : 1)
                                 .ThenBy(x => x.FieldType == typeof(string) ? 0 : 1)
                                 .ThenBy(x => x.Name).ToList();
                    }
                }

                return(fields);
            }
Пример #2
0
 public TypeKey(Type type, ImmutableSettings settings, bool includesTypeInfo, bool isolated)
 {
     Type             = type;
     Settings         = settings;
     IncludesTypeInfo = includesTypeInfo;
     Isolated         = isolated;
 }
        private static Expression?WriteArray(Type type,
                                             ParameterExpression stream,
                                             ParameterExpression output,
                                             Expression actualSource,
                                             ImmutableSettings settings,
                                             ImmutableHashSet <Type> visitedTypes,
                                             int depth)
        {
            if (type.IsArray)
            {
                var elementType = type.GetElementType() !;
                var dimensions  = type.GetArrayRank();

                var(elementSize, isRef) = TypeFields.GetSizeForType(elementType);

                var lengths = new List <ParameterExpression>();
                for (int i = 0; i < dimensions; ++i)
                {
                    lengths.Add(Expression.Variable(typeof(int), $"length{i}"));
                }

                var statements = new List <Expression>();

                statements.Add(ReserveConstantSize(stream, 4 * dimensions));
                statements.AddRange(lengths.Select((x, i) =>
                                                   Expression.Assign(x, Expression.Call(actualSource, "GetLength", Array.Empty <Type>(), Expression.Constant(i)))));
                statements.AddRange(lengths.Select(x =>
                                                   Expression.Call(stream, BinaryStreamMethods <TStream> .GenericMethods <int> .WriteValueMethodInfo, x)));

                // don't write anything else if lengths are zero
                var skipLabel = Expression.Label("skipWrite");
                statements.Add(
                    Expression.IfThen(
                        Expression.Equal(Expression.Constant(0), lengths.Aggregate((Expression)Expression.Empty(), (a, b) => a.NodeType == ExpressionType.Default ? (Expression)b : Expression.Or(a, b))),
                        Expression.Goto(skipLabel)
                        )
                    );

                if (IsBlittable(elementType) && dimensions < 3)
                {
                    statements.Add(WriteArrayOfBlittableValues(output, actualSource, stream, dimensions, elementType, elementSize));
                }
                else
                {
                    statements.Add(WriteArrayGeneral(output, actualSource, stream, dimensions, lengths, elementType, elementSize, settings, visitedTypes, depth));
                }

                statements.Add(Expression.Label(skipLabel));

                return(Expression.Block(lengths, statements));
            }

            return(null);
        }
 internal static bool MustUseReflectionToSetReadonly(ImmutableSettings settings) => SetFieldInfoNotReadonly == null || settings.ForceReflectionToSetReadonlyFields;