<PackageReference Include="System.Text.Json" Version="8.0.0-preview.1.23110.8" />

JsonPropertyInfo<T>

using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; namespace System.Text.Json.Serialization.Metadata { internal sealed class JsonPropertyInfo<T> : JsonPropertyInfo { private Func<object, T> _typedGet; private Action<object, T> _typedSet; private Func<object, T, bool> _shouldSerializeTyped; private JsonConverter<T> _typedEffectiveConverter; internal new Func<object, T> Get { get { return _typedGet; } set { SetGetter(value); } } internal new Action<object, T> Set { get { return _typedSet; } set { SetSetter(value); } } internal new Func<object, T, bool> ShouldSerialize { get { return _shouldSerializeTyped; } set { SetShouldSerialize(value); } } internal override object DefaultValue => default(T); internal override bool PropertyTypeCanBeNull => default(T) == null; internal new JsonConverter<T> EffectiveConverter => _typedEffectiveConverter; internal JsonPropertyInfo(Type declaringType, JsonTypeInfo declaringTypeInfo, JsonSerializerOptions options) : base(declaringType, typeof(T), declaringTypeInfo, options) { } private protected override void SetGetter(Delegate getter) { if ((object)getter == null) { _typedGet = null; _untypedGet = null; } else { Func<object, T> typedGetter = getter as Func<object, T>; if (typedGetter != null) { _typedGet = typedGetter; Func<object, object> func = getter as Func<object, object>; _untypedGet = ((func != null) ? func : ((Func<object, object>)((object obj) => typedGetter(obj)))); } else { Func<object, object> untypedGet = (Func<object, object>)getter; _typedGet = ((object obj) => (T)untypedGet(obj)); _untypedGet = untypedGet; } } } private protected override void SetSetter(Delegate setter) { if ((object)setter == null) { _typedSet = null; _untypedSet = null; } else { Action<object, T> typedSetter = setter as Action<object, T>; if (typedSetter != null) { _typedSet = typedSetter; Action<object, object> action = setter as Action<object, object>; _untypedSet = ((action != null) ? action : ((Action<object, object>)delegate(object obj, object value) { typedSetter(obj, (T)value); })); } else { Action<object, object> untypedSet = (Action<object, object>)setter; _typedSet = delegate(object obj, T value) { untypedSet(obj, value); }; _untypedSet = untypedSet; } } } private protected override void SetShouldSerialize(Delegate predicate) { if ((object)predicate == null) { _shouldSerializeTyped = null; _shouldSerialize = null; } else { Func<object, T, bool> typedPredicate = predicate as Func<object, T, bool>; if (typedPredicate != null) { _shouldSerializeTyped = typedPredicate; Func<object, object, bool> func = typedPredicate as Func<object, object, bool>; _shouldSerialize = ((func != null) ? func : ((Func<object, object, bool>)((object obj, object value) => typedPredicate(obj, (T)value)))); } else { Func<object, object, bool> untypedPredicate = (Func<object, object, bool>)predicate; _shouldSerializeTyped = ((object obj, T value) => untypedPredicate(obj, value)); _shouldSerialize = untypedPredicate; } } } private protected override void DetermineMemberAccessors(MemberInfo memberInfo) { PropertyInfo propertyInfo = memberInfo as PropertyInfo; if ((object)propertyInfo == null) { FieldInfo fieldInfo = memberInfo as FieldInfo; if ((object)fieldInfo != null) { Get = JsonSerializerOptions.MemberAccessorStrategy.CreateFieldGetter<T>(fieldInfo); if (!fieldInfo.IsInitOnly) Set = JsonSerializerOptions.MemberAccessorStrategy.CreateFieldSetter<T>(fieldInfo); } } else { bool flag = CustomAttributeExtensions.GetCustomAttribute<JsonIncludeAttribute>((MemberInfo)propertyInfo, false) != null; MethodInfo getMethod = propertyInfo.GetMethod; if (getMethod != (MethodInfo)null && (getMethod.IsPublic | flag)) Get = JsonSerializerOptions.MemberAccessorStrategy.CreatePropertyGetter<T>(propertyInfo); MethodInfo setMethod = propertyInfo.SetMethod; if (setMethod != (MethodInfo)null && (setMethod.IsPublic | flag)) Set = JsonSerializerOptions.MemberAccessorStrategy.CreatePropertySetter<T>(propertyInfo); } } internal JsonPropertyInfo(JsonPropertyInfoValues<T> propertyInfo, JsonSerializerOptions options) : this(propertyInfo.DeclaringType, (JsonTypeInfo)null, options) { string text = (propertyInfo.JsonPropertyName != null) ? propertyInfo.JsonPropertyName : ((options.PropertyNamingPolicy != null) ? options.PropertyNamingPolicy.ConvertName(propertyInfo.PropertyName) : propertyInfo.PropertyName); if (text == null) ThrowHelper.ThrowInvalidOperationException_SerializerPropertyNameNull(this); base.Name = text; base.MemberName = propertyInfo.PropertyName; base.MemberType = (propertyInfo.IsProperty ? MemberTypes.Property : MemberTypes.Field); base.SrcGen_IsPublic = propertyInfo.IsPublic; base.SrcGen_HasJsonInclude = propertyInfo.HasJsonInclude; base.IsExtensionData = propertyInfo.IsExtensionData; base.CustomConverter = propertyInfo.Converter; JsonIgnoreCondition? ignoreCondition = propertyInfo.IgnoreCondition; JsonIgnoreCondition jsonIgnoreCondition = JsonIgnoreCondition.Always; if (!((ignoreCondition.GetValueOrDefault() == jsonIgnoreCondition) & ignoreCondition.HasValue)) { Get = propertyInfo.Getter; Set = propertyInfo.Setter; } base.IgnoreCondition = propertyInfo.IgnoreCondition; base.JsonTypeInfo = propertyInfo.PropertyTypeInfo; base.NumberHandling = propertyInfo.NumberHandling; } private protected override void DetermineEffectiveConverter(JsonTypeInfo jsonTypeInfo) { _typedEffectiveConverter = (JsonConverter<T>)(_effectiveConverter = (base.Options.ExpandConverterFactory(base.CustomConverter, base.PropertyType)?.CreateCastingConverter<T>() ?? ((JsonTypeInfo<T>)jsonTypeInfo).EffectiveConverter)); } internal override object GetValueAsObject(object obj) { if (base.IsForTypeInfo) return obj; return Get(obj); } internal override bool GetMemberAndWriteJson(object obj, ref WriteStack state, Utf8JsonWriter writer) { T value = Get(obj); if (!EffectiveConverter.IsValueType && base.Options.ReferenceHandlingStrategy == ReferenceHandlingStrategy.IgnoreCycles && value != null && !state.IsContinuation && EffectiveConverter.ConverterStrategy != ConverterStrategy.Value && state.ReferenceResolver.ContainsReferenceForCycleDetection(value)) value = default(T); if (base.IgnoreDefaultValuesOnWrite) { if (IsDefaultValue(value)) return true; } else { Func<object, T, bool> shouldSerialize = ShouldSerialize; if (shouldSerialize != null && !shouldSerialize(obj, value)) return true; } if (value == null) { if (EffectiveConverter.HandleNullOnWrite) { if ((int)state.Current.PropertyState < 2) { state.Current.PropertyState = StackFramePropertyState.Name; writer.WritePropertyNameSection(base.EscapedNameSection); } int currentDepth = writer.CurrentDepth; EffectiveConverter.Write(writer, value, base.Options); if (currentDepth != writer.CurrentDepth) ThrowHelper.ThrowJsonException_SerializationConverterWrite(EffectiveConverter); } else writer.WriteNullSection(base.EscapedNameSection); return true; } if ((int)state.Current.PropertyState < 2) { state.Current.PropertyState = StackFramePropertyState.Name; writer.WritePropertyNameSection(base.EscapedNameSection); } return EffectiveConverter.TryWrite(writer, ref value, base.Options, ref state); } internal override bool GetMemberAndWriteJsonExtensionData(object obj, ref WriteStack state, Utf8JsonWriter writer) { T val = Get(obj); Func<object, T, bool> shouldSerialize = ShouldSerialize; if (shouldSerialize != null && !shouldSerialize(obj, val)) return true; if (val != null) return EffectiveConverter.TryWriteDataExtensionProperty(writer, val, base.Options, ref state); return true; } internal override bool ReadJsonAndSetMember(object obj, [System.Runtime.CompilerServices.ScopedRef] ref ReadStack state, ref Utf8JsonReader reader) { bool flag = reader.TokenType == JsonTokenType.Null; bool flag2; if (flag && !EffectiveConverter.HandleNullOnRead && !state.IsContinuation) { if (default(T) != null) ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(EffectiveConverter.TypeToConvert); if (!base.IgnoreNullTokensOnRead) Set(obj, default(T)); flag2 = true; state.Current.MarkRequiredPropertyAsRead(this); } else if (EffectiveConverter.CanUseDirectReadOrWrite && !state.Current.NumberHandling.HasValue) { if (!flag || !base.IgnoreNullTokensOnRead || default(T) != null) { T arg = EffectiveConverter.Read(ref reader, base.PropertyType, base.Options); Set(obj, arg); } flag2 = true; state.Current.MarkRequiredPropertyAsRead(this); } else { flag2 = true; if (!flag || !base.IgnoreNullTokensOnRead || default(T) != null || state.IsContinuation) { flag2 = EffectiveConverter.TryRead(ref reader, base.PropertyType, base.Options, ref state, out T value); if (flag2) { Set(obj, value); state.Current.MarkRequiredPropertyAsRead(this); } } } return flag2; } internal override bool ReadJsonAsObject([System.Runtime.CompilerServices.ScopedRef] ref ReadStack state, ref Utf8JsonReader reader, out object value) { bool result; if (reader.TokenType == JsonTokenType.Null && !EffectiveConverter.HandleNullOnRead && !state.IsContinuation) { if (default(T) != null) ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(EffectiveConverter.TypeToConvert); value = default(T); result = true; } else if (EffectiveConverter.CanUseDirectReadOrWrite && !state.Current.NumberHandling.HasValue) { value = EffectiveConverter.Read(ref reader, base.PropertyType, base.Options); result = true; } else { result = EffectiveConverter.TryRead(ref reader, base.PropertyType, base.Options, ref state, out T value2); value = value2; } return result; } private protected override void ConfigureIgnoreCondition(JsonIgnoreCondition? ignoreCondition) { if (ignoreCondition.HasValue) { switch (ignoreCondition.GetValueOrDefault()) { case JsonIgnoreCondition.Never: ShouldSerialize = ((object _, T value) => true); break; case JsonIgnoreCondition.Always: ShouldSerialize = ((object _, T value) => false); break; case JsonIgnoreCondition.WhenWritingNull: if (PropertyTypeCanBeNull) { ShouldSerialize = delegate(object _, T value) { if (default(T) != null) return !EqualityComparer<T>.Default.Equals(default(T), value); return value != null; }; base.IgnoreDefaultValuesOnWrite = true; } else ThrowHelper.ThrowInvalidOperationException_IgnoreConditionOnValueTypeInvalid(base.MemberName, base.DeclaringType); break; case JsonIgnoreCondition.WhenWritingDefault: ShouldSerialize = delegate(object _, T value) { if (default(T) != null) return !EqualityComparer<T>.Default.Equals(default(T), value); return value != null; }; base.IgnoreDefaultValuesOnWrite = true; break; } } } private static bool IsDefaultValue(T value) { if (default(T) != null) return EqualityComparer<T>.Default.Equals(default(T), value); return value == null; } } }