ホームページ >バックエンド開発 >C++ >複雑なオブジェクトをシリアル化するときに、JsonConvert 属性によって StackOverflowException が発生するのはなぜですか?

複雑なオブジェクトをシリアル化するときに、JsonConvert 属性によって StackOverflowException が発生するのはなぜですか?

DDD
DDDオリジナル
2025-01-20 15:40:13413ブラウズ

Why Does My JsonConvert Attribute Cause a StackOverflowException When Serializing Complex Objects?

[JsonConvert] 属性を使用した JSON.Net の StackOverflowException のトラブルシューティング

問題:

JSON.Net 内で [JsonConvert] 属性を使用して複雑なオブジェクトをフラット化された JSON にシリアル化すると、StackOverflowException.

がトリガーされる可能性があります。

根本原因:

提供されている FJson カスタム コンバーターは、再帰的メソッド (WriteJson) を使用してオブジェクト グラフを JSON ライターに書き込みます。この再帰的なアプローチには、さまざまなシナリオに対する十分な保護手段が欠けており、無限ループやスタック オーバーフロー エラーが発生する可能性があります。 これらのシナリオには次のものが含まれます:

  • ShouldSerialize*() メソッド: プロパティのシリアル化を決定するカスタム メソッドは、意図しない再帰を引き起こす可能性があります。
  • Null 値: Null 値を不適切に処理すると、問題が発生する可能性があります。
  • 値の型 (構造体): これらのデータ型は再帰プロセス内で正しく処理されない可能性があります。
  • JSON コンバーター属性: プロパティの既存のコンバーターは再帰ロジックを妨げる可能性があります。

解決策:

この StackOverflowException を解決する鍵は、WriteJson コンバーターの FJson メソッドを強化して、これらのエッジ ケースに対処することにあります。 改訂された WriteJson メソッドを以下に示します。

<code class="language-csharp">public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    if (ReferenceEquals(value, null))
    {
        writer.WriteNull();
        return;
    }

    var contract = (JsonObjectContract)serializer
        .ContractResolver
        .ResolveContract(value.GetType());

    writer.WriteStartObject();

    foreach (var property in contract.Properties)
    {
        if (property.Ignored) continue;
        if (!ShouldSerialize(property, value)) continue;

        var propertyName = property.PropertyName;
        var propertyValue = property.ValueProvider.GetValue(value);

        writer.WritePropertyName(propertyName);
        if (property.Converter != null && property.Converter.CanWrite)
        {
            property.Converter.WriteJson(writer, propertyValue, serializer);
        }
        else
        {
            serializer.Serialize(writer, propertyValue);
        }
    }

    writer.WriteEndObject();
}

private static bool ShouldSerialize(JsonProperty property, object instance)
{
    return property.ShouldSerialize == null || property.ShouldSerialize(instance);
}</code>

この改善されたバージョンは、null 値を明示的に処理し、カスタム ShouldSerialize メソッドを効果的に管理するための ShouldSerialize*() ヘルパー メソッドを組み込み、それによって StackOverflowException につながる無限再帰を防ぎます。 また、必要に応じてシリアル化を既存のコンバーターに正しく委任します。 この改訂されたアプローチでは、[JsonConvert] 属性と使用した場合にスタック オーバーフロー エラーが発生することなく、複雑なオブジェクトを確実にシリアル化できるようになります。

以上が複雑なオブジェクトをシリアル化するときに、JsonConvert 属性によって StackOverflowException が発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。