Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

148
Views
Why are the return types of .NET's System.Text.Json.JsonSerializer.Deserialize methods nullable when it doesn't return null?

Consider .NET 6's System.Text.Json.JsonSerializer.Deserialize method and its many overloads.

Each one returns either object? or TValue? which indicates that null could be returned. However, the documentation states that in the event of any error, an exception is thrown. Moreover, it also states that a valid value is returned (if an exception isn't thrown). Nowhere does it state that null could be returned. And in my experience of using it, null is never returned.

(The nullable return type is a problem if you turn on "nullability" in your project, because the compiler then starts warning you that the returned value could be null - which in my experience (and according to the documentation) just isn't true. It's this sort of thing that has me scurrying to switch nullability off again. I know I can suppress the warning, but I don't think that's the point.)

Is the documentation lacking? Can the methods really return null? If they can't, then why do we have nullable return types?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

According to RFC 7159 “null” (and “true” and “false”) will be valid JSON text. However, empty string is not a valid JSON.

over 4 years ago · Santiago Trujillo Report

0

  • TValue? Deserialize<TValue> is just a wrapper for Object? Deserialize(type: typeof(TValue)).
  • When #nullable annotations were added to C# 8.0, the System.Type type was not extended with support for those annotations.
    • Therefore, it is not possible for a generic-type in C# to know (at runtime) if a generic-type-parameter's concrete type-argument is a nullable-reference-type or a non-nullable-reference-type.
      • (This doesn't apply to Nullable<T>, of course)
  • So, at runtime, a call-site for Deserialize<TValue>() using either TValue := MyClass? or TValue := MyClass will behave identically because the Deserialize method has no idea if MyClass has the ? annotation or not.
    • The Deserialize<TValue> method only knows if TValue is a reference-type or not (via typeof(TValue)).
  • Therefore, if you instruct JsonSerializer to deserialize the string "null" (which is valid JSON) and if TValue is a reference type, then it will return null.
    • ...even if your TValue doesn't have ?. Remember that JsonSerializer doesn't (and cannot) know that!
  • Which is why the method's static return-type has the ? annotation, because if it didn't then it would be incorrectly asserting it never returns null.

It can be argued that JsonSerialize's designers could have added some more methods that allowed callers to statically assert non-null-ness, but they didn't, but you can if you really want to:

Like so:

public static TValue DeserializeNonNullObject<TValue>( String json )
    where TValue : class
{
    TValue? orNull = JsonSerializer.Deserialize<TValue>( json );
    return orNull ?? throw new JsonException( "Expected deserialized object to be non-null, but encountered null." );
}
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!