// 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; }
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; }
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; }
// 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; }
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); }