22// The .NET Foundation licenses this file to you under the MIT license.
33// See the LICENSE file in the project root for more information.
44
5+ using System . Collections . Generic ;
56using System . Diagnostics ;
67using System . Reflection ;
7- using System . Runtime . CompilerServices ;
88using System . Text . Json . Serialization ;
99
1010namespace System . Text . Json
@@ -16,8 +16,6 @@ namespace System.Text.Json
1616 /// or a type's converter, if the current instance is a <see cref="JsonClassInfo.PropertyInfoForClassInfo"/>.
1717 internal sealed class JsonPropertyInfo < T > : JsonPropertyInfo
1818 {
19- private static readonly T s_defaultValue = default ! ;
20-
2119 public Func < object , T > ? Get { get ; private set ; }
2220 public Action < object , T > ? Set { get ; private set ; }
2321
@@ -97,44 +95,45 @@ public override JsonConverter ConverterBase
9795
9896 public override bool GetMemberAndWriteJson ( object obj , ref WriteStack state , Utf8JsonWriter writer )
9997 {
100- bool success ;
10198 T value = Get ! ( obj ) ;
10299
100+ // Since devirtualization only works in non-shared generics,
101+ // the default comparer is uded only for value types for now.
102+ // For reference types there is a quick check for null.
103+ if ( IgnoreDefaultValuesOnWrite && (
104+ default ( T ) == null ? value == null : EqualityComparer < T > . Default . Equals ( default , value ) ) )
105+ {
106+ return true ;
107+ }
108+
103109 if ( value == null )
104110 {
105- Debug . Assert ( s_defaultValue == null && Converter . CanBeNull ) ;
111+ Debug . Assert ( Converter . CanBeNull ) ;
106112
107- success = true ;
108- if ( ! IgnoreDefaultValuesOnWrite )
113+ if ( Converter . HandleNull )
109114 {
110- if ( ! Converter . HandleNull )
115+ // No object, collection, or re-entrancy converter handles null.
116+ Debug . Assert ( Converter . ClassType == ClassType . Value ) ;
117+
118+ if ( state . Current . PropertyState < StackFramePropertyState . Name )
111119 {
112- writer . WriteNullSection ( EscapedNameSection ) ;
120+ state . Current . PropertyState = StackFramePropertyState . Name ;
121+ writer . WritePropertyNameSection ( EscapedNameSection ) ;
113122 }
114- else
123+
124+ int originalDepth = writer . CurrentDepth ;
125+ Converter . Write ( writer , value , Options ) ;
126+ if ( originalDepth != writer . CurrentDepth )
115127 {
116- // No object, collection, or re-entrancy converter handles null.
117- Debug . Assert ( Converter . ClassType == ClassType . Value ) ;
118-
119- if ( state . Current . PropertyState < StackFramePropertyState . Name )
120- {
121- state . Current . PropertyState = StackFramePropertyState . Name ;
122- writer . WritePropertyNameSection ( EscapedNameSection ) ;
123- }
124-
125- int originalDepth = writer . CurrentDepth ;
126- Converter . Write ( writer , value , Options ) ;
127- if ( originalDepth != writer . CurrentDepth )
128- {
129- ThrowHelper . ThrowJsonException_SerializationConverterWrite ( Converter ) ;
130- }
128+ ThrowHelper . ThrowJsonException_SerializationConverterWrite ( Converter ) ;
131129 }
132130 }
133- }
134- else if ( IgnoreDefaultValuesOnWrite && Converter . _defaultComparer . Equals ( s_defaultValue , value ) )
135- {
136- Debug . Assert ( s_defaultValue != null && ! Converter . CanBeNull ) ;
137- success = true ;
131+ else
132+ {
133+ writer . WriteNullSection ( EscapedNameSection ) ;
134+ }
135+
136+ return true ;
138137 }
139138 else
140139 {
@@ -144,10 +143,8 @@ public override bool GetMemberAndWriteJson(object obj, ref WriteStack state, Utf
144143 writer . WritePropertyNameSection ( EscapedNameSection ) ;
145144 }
146145
147- success = Converter . TryWrite ( writer , value , Options , ref state ) ;
146+ return Converter . TryWrite ( writer , value , Options , ref state ) ;
148147 }
149-
150- return success ;
151148 }
152149
153150 public override bool GetMemberAndWriteJsonExtensionData ( object obj , ref WriteStack state , Utf8JsonWriter writer )
@@ -179,7 +176,7 @@ public override bool ReadJsonAndSetMember(object obj, ref ReadStack state, ref U
179176 ThrowHelper . ThrowJsonException_DeserializeUnableToConvertValue ( Converter . TypeToConvert ) ;
180177 }
181178
182- Debug . Assert ( s_defaultValue == null ) ;
179+ Debug . Assert ( default ( T ) == null ) ;
183180
184181 if ( ! IgnoreDefaultValuesOnRead )
185182 {
0 commit comments