Skip to content

Instantly share code, notes, and snippets.

@richlander
Created September 11, 2020 21:32
Show Gist options
  • Save richlander/c02a4fd3202cdef64ad7bc1bbfbb9058 to your computer and use it in GitHub Desktop.
Save richlander/c02a4fd3202cdef64ad7bc1bbfbb9058 to your computer and use it in GitHub Desktop.
`JsonSerializer` support for immutable types
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>preview</LangVersion>
</PropertyGroup>
</Project>
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
var json = "{\"date\":\"2020-09-06T11:31:01.923395-07:00\",\"temperatureC\":-1,\"temperatureF\":31,\"summary\":\"Scorching\"} ";
var options = new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true,
IncludeFields = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var forecast = JsonSerializer.Deserialize<Forecast>(json, options);
Console.WriteLine(forecast.Date);
Console.WriteLine(forecast.TemperatureC);
Console.WriteLine(forecast.TemperatureF);
Console.WriteLine(forecast.Summary);
var roundTrippedJson = JsonSerializer.Serialize<Forecast>(forecast, options);
Console.WriteLine(roundTrippedJson);
public struct Forecast{
public DateTime Date {get;}
public int TemperatureC {get;}
public int TemperatureF {get;}
public string Summary {get;}
[JsonConstructor]
public Forecast(DateTime date, int temperatureC, int temperatureF, string summary) => (Date, TemperatureC, TemperatureF, Summary) = (date, temperatureC, temperatureF, summary);
}
@richlander
Copy link
Author

richlander commented Sep 11, 2020

It produces the following output:

rich@thundera jsonserializerimmutabletypes % dotnet run
9/6/2020 11:31:01 AM
-1
31
Scorching
{"date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"temperatureF":31,"summary":"Scorching"}

The JsonConstructor attribute is required to specify the constructor to use with structs. With classes, if there is only a single constructor, then the attribute is not required. Same with records.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment