次の方法で共有


XmlSerializer が ObsoleteAttribute でマークされたプロパティを無視しなくなりました

.NET 10 以降、 XmlSerializer の動作は、 ObsoleteAttribute 属性でマークされたプロパティの処理方法に関して変更されました。 以前は、 [Obsolete] でマークされたプロパティは、 [XmlIgnore]でマークされているかのように扱われ、XML シリアル化から除外されていました。 この動作は意図せずに修正されました。

この変更により、[Obsolete] プロパティが IsError に設定されていない限り、true でマークされたプロパティが既定でシリアル化されるようになりました。 IsErrortrue場合、シリアライザーは作成時にInvalidOperationExceptionをスローします。 さらに、AppContext スイッチ ( Switch.System.Xml.IgnoreObsoleteMembers) が導入され、開発者は必要に応じて以前の動作に戻すことができるようになります。

導入されたバージョン

.NET 10

以前の動作

以前のバージョンの .NET では、 [Obsolete] 属性でマークされたプロパティは、 [XmlIgnore]でマークされたプロパティと同様に、XML シリアル化から除外されていました。 この動作は予期せず、非推奨の API に関するコンパイル時の警告を提供するため、 [Obsolete] 属性の目的に合わせていません。

public class Example
{
    public string NormalProperty { get; set; } = "normal";

    [Obsolete("This property is deprecated")]
    public string ObsoleteProperty { get; set; } = "obsolete";

    [XmlIgnore]
    public string IgnoredProperty { get; set; } = "ignored";
}

var obj = new Example();
var serializer = new XmlSerializer(typeof(Example));
using var writer = new StringWriter();
serializer.Serialize(writer, obj);
Console.WriteLine(writer.ToString());

変更前の出力:

<Example>
  <NormalProperty>normal</NormalProperty>
</Example>

新しい動作

.NET 10 以降では、 [Obsolete] でマークされたプロパティは、既定では XML シリアル化から除外されなくなります。 その代わりに:

  • [Obsolete]属性が IsError = false (既定値) で適用されている場合、プロパティは通常どおりにシリアル化されます。
  • [Obsolete]属性が IsError = true で適用されている場合、XmlSerializerはシリアライザーの作成時にInvalidOperationExceptionをスローします。

前の動作セクションで示したのと同じコードを使用すると、変更後の出力は次のようになります。

<Example>
  <NormalProperty>normal</NormalProperty>
  <ObsoleteProperty>obsolete</ObsoleteProperty>
</Example>

プロパティに [Obsolete(IsError = true)] を適用すると、シリアライザーの作成時に次の例外がスローされます。

System.InvalidOperationException: メンバー 'ObsoleteProperty' は ObsoleteAttribute でマークされ、IsError が true に設定されているため、シリアル化できません。

[Obsolete]としてマークされているプロパティは、データが XML に存在する場合、常に正常に逆シリアル化されます。 この変更により、プロパティ [Obsolete] オブジェクトから XML への "ラウンド トリップ" とオブジェクトへの "ラウンド トリップ" が可能になりますが、新しい動作は "ラウンド トリップ" のシリアル化の半分 (オブジェクトから XML) にのみ影響します。

破壊的変更の種類

この変更は 動作の変更です。

変更の理由

[Obsolete][XmlIgnore]と同等として扱う以前の動作は意図しておらず、[Obsolete]属性の目的と矛盾していました。 この変更により、 [Obsolete] はコンパイル時の警告を提供する目的でのみ使用され、実行時のシリアル化動作には影響しません。 AppContext スイッチの導入により、開発者は必要に応じて従来の動作にオプトインできます。

[Obsolete]プロパティが XML シリアル化から除外された以前の動作に依存していないかどうかをコードベースで確認します。 この動作が必要な場合は、次のように AppContext スイッチ Switch.System.Xml.IgnoreObsoleteMembers 有効にします。

AppContext.SetSwitch("Switch.System.Xml.IgnoreObsoleteMembers", true);

[Obsolete(IsError = true)]でマークされ、シリアル化されているプロパティがある場合は、実行時の例外を回避するために、[Obsolete]属性を削除するか、IsError = falseを設定するようにコードを更新します。

影響を受ける API