Beispiel #1
0
        // todo: to avoid hashtable lookups, cache this:
        //public JsonClassInfo ClassInfo;

        public JsonPropertyInfo(Type parentClassType, Type propertyType, PropertyInfo propertyInfo, Type elementType, JsonSerializerOptions options)
        {
            ParentClassType = parentClassType;
            PropertyType    = propertyType;
            PropertyInfo    = propertyInfo;
            ClassType       = JsonClassInfo.GetClassType(propertyType);
            if (elementType != null)
            {
                ElementClassInfo = options.GetOrAddClass(elementType);
            }

            IsNullableType = propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable <>);
            CanBeNull      = IsNullableType || !propertyType.IsValueType;
        }
Beispiel #2
0
 public virtual void Initialize(
     Type parentClassType,
     Type declaredPropertyType,
     Type runtimePropertyType,
     PropertyInfo propertyInfo,
     Type elementType,
     JsonSerializerOptions options)
 {
     ParentClassType      = parentClassType;
     DeclaredPropertyType = declaredPropertyType;
     RuntimePropertyType  = runtimePropertyType;
     PropertyInfo         = propertyInfo;
     ClassType            = JsonClassInfo.GetClassType(runtimePropertyType);
     _elementType         = elementType;
     Options        = options;
     IsNullableType = runtimePropertyType.IsGenericType && runtimePropertyType.GetGenericTypeDefinition() == typeof(Nullable <>);
     CanBeNull      = IsNullableType || !runtimePropertyType.IsValueType;
 }
Beispiel #3
0
        internal JsonPropertyInfo(
            Type parentClassType,
            Type declaredPropertyType,
            Type runtimePropertyType,
            PropertyInfo propertyInfo,
            Type elementType,
            JsonSerializerOptions options)
        {
            ParentClassType      = parentClassType;
            DeclaredPropertyType = declaredPropertyType;
            RuntimePropertyType  = runtimePropertyType;
            PropertyInfo         = propertyInfo;
            ClassType            = JsonClassInfo.GetClassType(runtimePropertyType);
            if (elementType != null)
            {
                ElementClassInfo = options.GetOrAddClass(elementType);
            }

            IsNullableType = runtimePropertyType.IsGenericType && runtimePropertyType.GetGenericTypeDefinition() == typeof(Nullable <>);
            CanBeNull      = IsNullableType || !runtimePropertyType.IsValueType;
        }
Beispiel #4
0
        // todo: to minimize hashtable lookups, cache JsonClassInfo:
        //public JsonClassInfo ClassInfo;

        public virtual void Initialize(
            Type parentClassType,
            Type declaredPropertyType,
            Type runtimePropertyType,
            PropertyInfo propertyInfo,
            Type elementType,
            JsonSerializerOptions options)
        {
            ParentClassType      = parentClassType;
            DeclaredPropertyType = declaredPropertyType;
            RuntimePropertyType  = runtimePropertyType;
            PropertyInfo         = propertyInfo;
            ClassType            = JsonClassInfo.GetClassType(runtimePropertyType);
            if (elementType != null)
            {
                Debug.Assert(ClassType == ClassType.Enumerable || ClassType == ClassType.Dictionary);
                ElementClassInfo = options.GetOrAddClass(elementType);
            }

            IsNullableType = runtimePropertyType.IsGenericType && runtimePropertyType.GetGenericTypeDefinition() == typeof(Nullable <>);
            CanBeNull      = IsNullableType || !runtimePropertyType.IsValueType;
        }
Beispiel #5
0
        private static bool HandleObject(
            JsonSerializerOptions options,
            ref Utf8JsonWriter writer,
            ref WriteStack state)
        {
            Debug.Assert(state.Current.JsonClassInfo.ClassType == ClassType.Object);

            JsonPropertyInfo jsonPropertyInfo  = state.Current.JsonClassInfo.GetProperty(state.Current.PropertyIndex);
            ClassType        propertyClassType = jsonPropertyInfo.ClassType;

            bool   obtainedValue = false;
            object currentValue  = null;

            // Check for polymorphism.
            if (jsonPropertyInfo.RuntimePropertyType == typeof(object))
            {
                Debug.Assert(propertyClassType == ClassType.Object);

                currentValue  = jsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue, options);
                obtainedValue = true;

                if (currentValue != null)
                {
                    Type runtimeType = currentValue.GetType();

                    // Ignore object() instances since they are handled as an empty object.
                    if (runtimeType != typeof(object))
                    {
                        propertyClassType = JsonClassInfo.GetClassType(runtimeType);
                        jsonPropertyInfo  = state.Current.JsonClassInfo.CreatePolymorphicProperty(jsonPropertyInfo, runtimeType, options);
                    }
                }
            }

            state.Current.JsonPropertyInfo = jsonPropertyInfo;

            if (propertyClassType == ClassType.Value)
            {
                jsonPropertyInfo.Write(options, ref state.Current, ref writer);
                state.Current.NextProperty();
                return(true);
            }

            // A property that returns an enumerator keeps the same stack frame.
            if (propertyClassType == ClassType.Enumerable)
            {
                bool endOfEnumerable = HandleEnumerable(jsonPropertyInfo.ElementClassInfo, options, ref writer, ref state);
                if (endOfEnumerable)
                {
                    state.Current.NextProperty();
                }

                return(endOfEnumerable);
            }

            // A property that returns an object.
            if (!obtainedValue)
            {
                currentValue = jsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue, options);
            }

            if (currentValue != null)
            {
                // A new stack frame is required.
                JsonPropertyInfo previousPropertyInfo = state.Current.JsonPropertyInfo;

                state.Current.NextProperty();

                JsonClassInfo nextClassInfo = options.GetOrAddClass(jsonPropertyInfo.RuntimePropertyType);
                state.Push(nextClassInfo, currentValue);

                // Set the PropertyInfo so we can obtain the property name in order to write it.
                state.Current.JsonPropertyInfo = previousPropertyInfo;
            }
            else
            {
                if (!jsonPropertyInfo.IgnoreNullPropertyValueOnWrite(options))
                {
                    writer.WriteNull(jsonPropertyInfo._escapedName);
                }

                state.Current.NextProperty();
            }

            return(true);
        }