web-dev-qa-db-ja.com

パブリックプロパティがXmlSerializerによってシリアル化されないのはなぜですか?

これは私が長い間苦労してきたものなので、どこかで文書化すると思いました。 (質問をしたり答えたりしたことに対する謝罪。)

(C#.net 2.0)XmlSerializerによってシリアル化されているクラスがあり、新しいパブリックプロパティを追加しましたが、出力XMLには含まれていませんでした。

それは私が見つけることができるどこのドキュメントでも言及されていませんが、パブリックプロパティにはセットとシリアル化が必要です!これは、シリアル化する場合は同じファイルから逆シリアル化することを前提としているため、setとgetの両方を持つプロパティのみをシリアル化することを前提としているためだと思います。

56
Rory

前述のように、ほとんどのプロパティにはゲッターとセッターの両方が必要です。これの主な例外はリストです-例えば:

_private readonly List<Foo> bar = new List<Foo>();
public List<Foo> Bar {get { return bar; } } // works fine
_

それはうまくいくでしょう。ただし、XmlSerializerfindssetterの場合-パブリックであることを要求します。以下はnot動作します:

_public List<Foo> Bar {get; private set;} // FAIL
_

シリアル化されないその他の理由:

  • getおよびsetでパブリックではありません(またはフィールドのreadonlyです)
  • _[DefaultValue]_属性を持ち、その値を持っています
  • falseを返したpublic bool ShouldSerializeFoo()メソッドがあります
  • falseを返したパブリック_bool FooSpecified {get;set;}_プロパティまたはフィールドがあります
  • _[XmlIgnore]_とマークされています
  • _[Obsolete]_とマークされています

これらのいずれかにより、シリアル化されません

88
Marc Gravell

Getter + setterについてのポイントは、「 Intro to Xml Serialization 」ページの3番目の段落で説明されています。実際には、コールアウトボックスにあります。お見逃しなく!

Intro-to-XML Serialization http://www.freeimagehosting.net/uploads/2f04fea2db.png

(Freeimagehosting.netを少し楽しんでいます)

7
Cheeso

適切なセッターを実装したくない場合(オブジェクトの値を逆シリアル化または変更したくないため)、このset { }のようなダミーのセッターを使用するだけで、XMLSerializerが機能します。しかし、セッターを使用しても何も起こりません...

i.E.

public string ID { get { return _item.ID.ToString(); } set { } }
5
JonSchn

また、nullを返すプロパティはシリアル化されません!

4
anonymous

コレクションのシリアル化についてもう1つ追加します。

XmlSerializerはインターフェイスのコレクションを無視します!

そしてそれはignoreを意味します。次のような行では例外が発生します:

public IFoo Foo { get; set; }

あなたはnot例外を取得します:

public ICollection<IFoo> LotsOfFoos { get { return this.fooBackingField; } }
2

クラスがリストを継承し、独自のメンバーも持っている場合、リストの要素のみがシリアル化されます。クラスメンバーに存在するデータはキャプチャされません。これを理解するのに時間がかかりました!

2
Nanda

IXmlSerializerを実装し、手動でシリアル化を行うことができます。また、コンストラクター/プライベートフィールドの割り当てを使用してプロパティをシリアル化することでメリットが得られます。

0
Shimmy