Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Generowanie źródła może być używane w dwóch trybach: optymalizacji opartej na metadanych i serializacji. W tym artykule opisano różne tryby.
Aby uzyskać informacje na temat używania trybów generowania źródła, zobacz Jak używać generowania źródła w programie System.Text.Json.
Tryb oparty na metadanych
Generowanie źródła umożliwia przeniesienie procesu zbierania metadanych ze środowiska uruchomieniowego do czasu kompilacji. Podczas kompilacji metadane są zbierane, a pliki kodu źródłowego są generowane. Wygenerowane pliki kodu źródłowego są automatycznie kompilowane jako integralna część aplikacji. Ta technika eliminuje zbieranie metadanych środowiska uruchomieniowego, co zwiększa wydajność zarówno serializacji, jak i deserializacji.
Ulepszenia wydajności zapewniane przez generowanie kodu źródłowego mogą być znaczne. Na przykład wyniki testów wykazały zmniejszenie czasu uruchamiania o 40% lub więcej, zmniejszenie prywatnej pamięci, zwiększenie szybkości przepustowości (w trybie optymalizacji serializacji) oraz zmniejszenie rozmiaru aplikacji.
Niepubliczne składowe i konstruktory
Domyślnie zarówno tryb refleksji, jak i tryb generowania kodu źródłowego uwzględniają w kontrakcie serializacji tylko właściwości i pola public.
Począwszy od platformy .NET 11, generowanie kodu źródłowego obsługuje składowe, które zostaną jawnie oznaczone atrybutem [JsonInclude]. Element może mieć wartość private, internal lub protected. Obsługuje również akcesory private, internal i protected dla właściwości, które oznaczysz za pomocą [JsonInclude]. Generowanie kodu źródłowego obsługuje również niedostępne konstruktory oznaczone atrybutem [JsonConstructor].
W platformie .NET 11 wygenerowane akcesory używają UnsafeAccessorAttribute.
Ustawiający wygenerowany przez źródło dla initwłaściwości -only jest uruchamiany tylko wtedy, gdy ładunek JSON zawiera właściwość . Właściwość tylko init, którą pomija ładunek danych, zachowuje wartość z inicjalizatora właściwości.
W .NET 10 i starszych wersjach generowanie źródła ma następujące ograniczenia:
- Generowanie kodu źródłowego nie obsługuje składowych
privateani akcesorówprotected. Jeśli oznaczysz taką składową za pomocą[JsonInclude], serializator zgłosi wyjątek NotSupportedException w czasie wykonywania. - Generowanie kodu źródłowego obsługuje składowe
internali akcesory tylko wtedy, gdy są one dostępne dla wygenerowanego elementu JsonSerializerContext w tym samym zestawie. - Generowanie kodu źródłowego nie obsługuje konstruktorów niedostępnych dla wygenerowanego kontekstu, nawet jeśli oznaczysz je znacznikiem
[JsonConstructor].
Znane problemy
Aby uzyskać informacje o innych znanych problemach z generowaniem źródła, zobacz problemy z usługą GitHub oznaczone jako "source-generator" w repozytorium dotnet/runtime .
Tryb optymalizacji serializacji (szybka ścieżka)
JsonSerializer ma wiele funkcji, które umożliwiają dostosowanie wyników serializacji, takich jak polityki nazewnictwa i zachowanie referencji. Obsługa wszystkich tych funkcji powoduje pewne obciążenie związane z wydajnością. Generowanie kodu źródłowego może poprawić wydajność serializacji poprzez generowanie zoptymalizowanego kodu, który bezpośrednio używa Utf8JsonWriter.
Tryb optymalizacji serializacji emituje metody serializacji szybkiej ścieżki, ale nie metadane serializacji. Serializacja szybkiej ścieżki jest ograniczona w tym, co może osiągnąć; nie obsługuje ona asynchronicznej serializacji ani żadnego trybu deserializacji.
Ponadto zoptymalizowany kod nie obsługuje wszystkich funkcji serializacji, które JsonSerializer obsługują. Serializator wykrywa, czy zoptymalizowany kod może być używany i wraca do domyślnego kodu serializacji, jeśli nie są określone nieobsługiwane opcje. Na przykład JsonNumberHandling.AllowReadingFromString nie ma zastosowania do pisania, dlatego określenie tej opcji nie powoduje powrotu do domyślnego kodu.
W poniższej tabeli przedstawiono opcje w JsonSerializerOptions, które są obsługiwane przez szybką ścieżkę serializacji:
| Opcja serializacji | Obsługiwane dla ścieżki szybkiego dostępu |
|---|---|
| AllowTrailingCommas | ✔️ |
| Converters | ❌ |
| DefaultBufferSize | ✔️ |
| DefaultIgnoreCondition | ✔️ |
| DictionaryKeyPolicy | ❌ |
| Encoder | ❌ |
| IgnoreNullValues | ❌ |
| IgnoreReadOnlyFields | ✔️ |
| IgnoreReadOnlyProperties | ✔️ |
| IncludeFields | ✔️ |
| MaxDepth | ✔️ |
| NumberHandling | ❌ |
| PropertyNamingPolicy | ✔️ |
| ReferenceHandler | ❌ |
| TypeInfoResolver | ✔️ |
| WriteIndented | ✔️ |
(Następujące opcje nie są obsługiwane, ponieważ dotyczą tylko deserializacji: PropertyNameCaseInsensitive, ReadCommentHandling, i UnknownTypeHandling.)
W poniższej tabeli przedstawiono, które atrybuty są obsługiwane dla szybkiej ścieżki serializacji.
| Atrybut | Obsługiwane dla ścieżki szybkiego dostępu |
|---|---|
| JsonConstructorAttribute | ❌ |
| JsonConverterAttribute | ❌ |
| JsonDerivedTypeAttribute | ✔️ |
| JsonExtensionDataAttribute | ❌ |
| JsonIgnoreAttribute | ✔️ |
| JsonIncludeAttribute | ✔️ |
| JsonNumberHandlingAttribute | ❌ |
| JsonPolymorphicAttribute | ✔️ |
| JsonPropertyNameAttribute | ✔️ |
| JsonPropertyOrderAttribute | ✔️ |
| JsonRequiredAttribute | ✔️ |
Jeśli dla typu określono nieobsługiwaną opcję lub atrybut, serializator powraca do trybu metadanych, zakładając, że generator źródła został skonfigurowany do generowania metadanych. W takim przypadku zoptymalizowany kod nie jest używany podczas serializacji tego typu, ale może być używany dla innych typów. Dlatego ważne jest przeprowadzenie testów wydajnościowych przy użyciu opcji i obciążeń, aby określić, ile korzyści można uzyskać z trybu optymalizacji serializacji. Ponadto możliwość powrotu do JsonSerializer kodu wymaga trybu metadanych. W przypadku wybrania tylko trybu optymalizacji serializacji serializacja może zakończyć się niepowodzeniem dla typów lub opcji, które muszą wrócić do JsonSerializer kodu.