Události
Vytváření inteligentních aplikací
17. 3. 23 - 21. 3. 23
Připojte se k řadě meetupů a vytvořte škálovatelná řešení AI založená na skutečných případech použití s kolegy vývojáři a odborníky.
ZaregistrovatTento prohlížeč se už nepodporuje.
Upgradujte na Microsoft Edge, abyste mohli využívat nejnovější funkce, aktualizace zabezpečení a technickou podporu.
Neměnný typ je takový, který vám brání ve změně jakékoli vlastnosti nebo hodnot polí objektu po vytvoření instance. Typ může být záznam, nemá žádné veřejné vlastnosti nebo pole, mají vlastnosti jen pro čtení nebo mají vlastnosti s privátními nebo inicializačními settery. System.String je příkladem neměnného typu. System.Text.Json poskytuje různé způsoby, jak můžete deserializovat JSON na neměnné typy.
Ve výchozím nastavení System.Text.Json
používá výchozí veřejný konstruktor bez parametrů. Můžete ale říct, že má použít parametrizovaný konstruktor, který umožňuje deserializovat neměnnou třídu nebo strukturu.
Pokud je jediný konstruktor pro třídu parametrizovaný, použije se tento konstruktor.
Pro strukturu nebo třídu s více konstruktory určete, který se má použít použitím [JsonConstructor] atributu. Pokud se atribut nepoužívá, veřejný konstruktor bez parametrů se vždy používá, pokud je k dispozici.
Následující příklad používá atribut [JsonConstructor]
:
using System.Text.Json;
using System.Text.Json.Serialization;
namespace ImmutableTypes
{
public struct Forecast
{
public DateTime Date { get; }
public int TemperatureC { get; }
public string Summary { get; }
[JsonConstructor]
public Forecast(DateTime date, int temperatureC, string summary) =>
(Date, TemperatureC, Summary) = (date, temperatureC, summary);
}
public class Program
{
public static void Main()
{
string json = """
{
"date":"2020-09-06T11:31:01.923395-07:00",
"temperatureC":-1,
"summary":"Cold"
}
""";
Console.WriteLine($"Input JSON: {json}");
var options = JsonSerializerOptions.Web;
Forecast forecast = JsonSerializer.Deserialize<Forecast>(json, options);
Console.WriteLine($"forecast.Date: {forecast.Date}");
Console.WriteLine($"forecast.TemperatureC: {forecast.TemperatureC}");
Console.WriteLine($"forecast.Summary: {forecast.Summary}");
string roundTrippedJson =
JsonSerializer.Serialize<Forecast>(forecast, options);
Console.WriteLine($"Output JSON: {roundTrippedJson}");
}
}
}
// Produces output like the following example:
//
//Input JSON: { "date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"summary":"Cold"}
//forecast.Date: 9 / 6 / 2020 11:31:01 AM
//forecast.TemperatureC: -1
//forecast.Summary: Cold
//Output JSON: { "date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"summary":"Cold"}
Imports System.Text.Json
Imports System.Text.Json.Serialization
Namespace ImmutableTypes
Public Structure Forecast
Public ReadOnly Property [Date] As Date
Public ReadOnly Property TemperatureC As Integer
Public ReadOnly Property Summary As String
<JsonConstructor>
Public Sub New([Date] As Date, TemperatureC As Integer, Summary As String)
Me.Date = [Date]
Me.TemperatureC = TemperatureC
Me.Summary = Summary
End Sub
End Structure
Public NotInheritable Class Program
Public Shared Sub Main()
Dim json As String = "{""date"":""2020-09-06T11:31:01.923395-07:00"",""temperatureC"":-1,""summary"":""Cold""}"
Console.WriteLine($"Input JSON: {json}")
Dim forecast1 As Forecast = JsonSerializer.Deserialize(Of Forecast)(json, JsonSerializerOptions.Web)
Console.WriteLine($"forecast.Date: {forecast1.[Date]}")
Console.WriteLine($"forecast.TemperatureC: {forecast1.TemperatureC}")
Console.WriteLine($"forecast.Summary: {forecast1.Summary}")
Dim roundTrippedJson As String = JsonSerializer.Serialize(forecast1, JsonSerializerOptions.Web)
Console.WriteLine($"Output JSON: {roundTrippedJson}")
End Sub
End Class
End Namespace
' Produces output like the following example:
'
'Input JSON: { "date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"summary":"Cold"}
'forecast.Date: 9 / 6 / 2020 11:31:01 AM
'forecast.TemperatureC: -1
'forecast.Summary: Cold
'Output JSON: { "date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"summary":"Cold"}
V rozhraní .NET 7 a starších verzích lze atribut [JsonConstructor]
použít pouze s veřejnými konstruktory.
Názvy parametrů parametrizovaného konstruktoru musí odpovídat názvům a typům vlastností. Porovnávání nerozlišuje malá a velká písmena a parametr konstruktoru musí odpovídat názvu skutečné vlastnosti, i když použijete [JsonPropertyName] k přejmenování vlastnosti. V následujícím příkladu se název vlastnosti TemperatureC
změní na celsius
ve formátu JSON, ale parametr konstruktoru má stále název temperatureC
:
using System.Text.Json;
using System.Text.Json.Serialization;
namespace ImmutableTypesCtorParms
{
public readonly struct Forecast
{
public DateTime Date { get; }
[JsonPropertyName("celsius")]
public int TemperatureC { get; }
public string Summary { get; }
[JsonConstructor]
public Forecast(DateTime date, int temperatureC, string summary) =>
(Date, TemperatureC, Summary) = (date, temperatureC, summary);
}
public class Program
{
public static void Main()
{
string json = """
{
"date":"2020-09-06T11:31:01.923395-07:00",
"celsius":-1,
"summary":"Cold"
}
""";
Console.WriteLine($"Input JSON: {json}");
var options = JsonSerializerOptions.Web;
Forecast forecast = JsonSerializer.Deserialize<Forecast>(json, options);
Console.WriteLine($"forecast.Date: {forecast.Date}");
Console.WriteLine($"forecast.TemperatureC: {forecast.TemperatureC}");
Console.WriteLine($"forecast.Summary: {forecast.Summary}");
string roundTrippedJson =
JsonSerializer.Serialize<Forecast>(forecast, options);
Console.WriteLine($"Output JSON: {roundTrippedJson}");
}
}
}
// Produces output like the following example:
//
//Input JSON: { "date":"2020-09-06T11:31:01.923395-07:00","celsius":-1,"summary":"Cold"}
//forecast.Date: 9 / 6 / 2020 11:31:01 AM
//forecast.TemperatureC: -1
//forecast.Summary: Cold
//Output JSON: { "date":"2020-09-06T11:31:01.923395-07:00","celsius":-1,"summary":"Cold"}
Kromě [JsonPropertyName]
podporují následující atributy deserializaci s parametrizovanými konstruktory:
Záznamy jsou také podporovány pro serializaci i deserializaci, jak je znázorněno v následujícím příkladu:
using System.Text.Json;
namespace Records
{
public record Forecast(DateTime Date, int TemperatureC)
{
public string? Summary { get; init; }
};
public class Program
{
public static void Main()
{
Forecast forecast = new(DateTime.Now, 40)
{
Summary = "Hot!"
};
string forecastJson = JsonSerializer.Serialize<Forecast>(forecast);
Console.WriteLine(forecastJson);
Forecast? forecastObj = JsonSerializer.Deserialize<Forecast>(forecastJson);
Console.WriteLine(forecastObj);
}
}
}
// Produces output like the following example:
//
//{ "Date":"2020-10-21T15:26:10.5044594-07:00","TemperatureC":40,"Summary":"Hot!"}
//Forecast { Date = 10 / 21 / 2020 3:26:10 PM, TemperatureC = 40, Summary = Hot! }
Na názvy vlastností můžete použít libovolný atribut s použitím cíle property:
u atributu. Další informace o pozičních záznamech najdete v článku o záznamech v referenci jazyka C#.
Použití neveřejného přístupového objektu u vlastnosti můžete povolit pomocí atributu [JsonInclude], jak je znázorněno v následujícím příkladu:
using System.Text.Json;
using System.Text.Json.Serialization;
namespace NonPublicAccessors
{
public class Forecast
{
public DateTime Date { get; init; }
[JsonInclude]
public int TemperatureC { get; private set; }
[JsonInclude]
public string? Summary { private get; set; }
};
public class Program
{
public static void Main()
{
string json = """
{
"Date":"2020-10-23T09:51:03.8702889-07:00",
"TemperatureC":40,
"Summary":"Hot"
}
""";
Console.WriteLine($"Input JSON: {json}");
Forecast forecastDeserialized = JsonSerializer.Deserialize<Forecast>(json)!;
Console.WriteLine($"Date: {forecastDeserialized.Date}");
Console.WriteLine($"TemperatureC: {forecastDeserialized.TemperatureC}");
json = JsonSerializer.Serialize<Forecast>(forecastDeserialized);
Console.WriteLine($"Output JSON: {json}");
}
}
}
// Produces output like the following example:
//
//Input JSON: { "Date":"2020-10-23T09:51:03.8702889-07:00","TemperatureC":40,"Summary":"Hot"}
//Date: 10 / 23 / 2020 9:51:03 AM
//TemperatureC: 40
//Output JSON: { "Date":"2020-10-23T09:51:03.8702889-07:00","TemperatureC":40,"Summary":"Hot"}
Imports System.Text.Json
Imports System.Text.Json.Serialization
Namespace NonPublicAccessors
Public Class Forecast
Public Property [Date] As Date
Private _temperatureC As Integer
<JsonInclude>
Public Property TemperatureC As Integer
Get
Return _temperatureC
End Get
Private Set(Value As Integer)
_temperatureC = Value
End Set
End Property
Private _summary As String
<JsonInclude>
Public Property Summary As String
Private Get
Return _summary
End Get
Set(Value As String)
_summary = Value
End Set
End Property
End Class
Public NotInheritable Class Program
Public Shared Sub Main()
Dim json As String = "{""Date"":""2020-10-23T09:51:03.8702889-07:00"",""TemperatureC"":40,""Summary"":""Hot""}"
Console.WriteLine($"Input JSON: {json}")
Dim forecastDeserialized As Forecast = JsonSerializer.Deserialize(Of Forecast)(json)
Console.WriteLine($"Date: {forecastDeserialized.[Date]}")
Console.WriteLine($"TemperatureC: {forecastDeserialized.TemperatureC}")
json = JsonSerializer.Serialize(forecastDeserialized)
Console.WriteLine($"Output JSON: {json}")
End Sub
End Class
End Namespace
' Produces output like the following example:
'
'Input JSON: { "Date":"2020-10-23T09:51:03.8702889-07:00","TemperatureC":40,"Summary":"Hot"}
'Date: 10 / 23 / 2020 9:51:03 AM
'TemperatureC: 40
'Output JSON: { "Date":"2020-10-23T09:51:03.8702889-07:00","TemperatureC":40,"Summary":"Hot"}
Zahrnutím vlastnosti s privátním setterem můžete tuto vlastnost stále deserializovat.
V .NET 8 a novějších verzích můžete také použít atribut [JsonInclude] k zahrnutí neveřejných členů do smlouvy o serializaci pro daný typ.
Poznámka
V režimu generování zdroje nemůžete serializovat private
členy ani použít private
přístupové objekty tak, že je označíte atributem [JsonInclude]. A můžete serializovat pouze internal
členy nebo použít internal
přístupové objekty, pokud jsou ve stejném sestavení jako vygenerovaný JsonSerializerContext.
V .NET 8 a novějších verzích je možné deserializovat také vlastnosti jen pro čtení, nebo vlastnosti, které nemají privátní nebo veřejný setter. I když nemůžete změnit instanci, na kterou vlastnost odkazuje, pokud je typ vlastnosti proměnlivý, můžete ji upravit. Do seznamu můžete například přidat prvek. Chcete-li deserializovat vlastnost jen pro čtení, je nutné nastavit její chování při vytváření objektů tak, aby naplnit místo nahradit. Můžete například anotovat vlastnost pomocí atributu JsonObjectCreationHandlingAttribute.
class A
{
[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
public List<int> Numbers1 { get; } = new List<int>() { 1, 2, 3 };
}
Další informace naleznete v tématu Naplnění inicializovaných vlastností.
Zpětná vazba k produktu .NET
.NET je open source projekt. Vyberte odkaz pro poskytnutí zpětné vazby:
Události
Vytváření inteligentních aplikací
17. 3. 23 - 21. 3. 23
Připojte se k řadě meetupů a vytvořte škálovatelná řešení AI založená na skutečných případech použití s kolegy vývojáři a odborníky.
ZaregistrovatŠkolení
Modul
Implement Class Properties and Methods - Training
Learn how to implement read-write, read-only, and write-only class properties using property accessors and access modifiers, and how to implement methods and extension methods for a class.