セッターのないプロパティがシリアル化されないのはなぜですか


100

シリアル化可能なクラスがあり、クラスのプロパティの1つがGuidゲッターでを生成します。このプロパティはセッターを実装せず、シリアル化中は無視されます。それはなぜですか?プロパティをシリアル化するために、常にセッターを実装する必要があります。

[Serializable]
public class Example
{
    [XmlAttribute("id")]
    public string Id
    {
        get
        {
             return Guid.NewGuid().ToString();
        }
    }
}

空のセッターを実装してみたところ、正しくシリアライズされました。

[Serializable]
public class Example
{
    [XmlAttribute("id")]
    public string Id
    {
        get
        {
             return Guid.NewGuid().ToString();
        }
        set {}
    }
}

更新

値が決して変化しないプロパティ、または値が内部で生成されるプロパティをどのように定義すればよいか指摘できますか?


1
2番目の例は正しくシリアライズします...しかし、それをデシリアライズしようとするとどうなりますか?
LightStriker、

YAXLib [++ ]をお試しください
シーナイラバニア

3
ちなみに、XMLシリアライザは無視し[Serializable]ます。
John Saunders、

@JohnSaunders知らなかった。
Konstantin Dinev

回答:


59

これは、XmlSerializer読み取り専用プロパティをシリアル化しないという制限事項です。2番目の例で行ったのは、本質的にはシリアル化するためのハックですが、後で逆シリアル化する必要がある場合は役に立ちません。

または、DataContractSerializerを使用するように切り替えることもできます。


8
DataContractSerializerにもセッターが必要です。これは、1つのタイプの操作(逆シリアル化など)にのみ使用する場合がありますが、宣言は両方に必要であるので、制限です。シリアル化プロセスは、シリアル化しようとするときに値の処理方法を認識しません。オブジェクトへのXML。
ryadavilli

7
@ryadavilli [DataMember]を使用してシリアル化されているとマークされたものDataContractSerializer(読み取り専用かどうか)。
ジェームズ

1
@James同じことをしようとしたときにコンパイル時エラーが発生したため、上記を記述しました。さて、コードに戻ってセッターを削除すると、正常にコンパイルされたようです。これは非常に奇妙で、おそらくこれについてもっと研究するための宿題です。
ryadavilli

3
ああ、ようやく私の混乱の原因がわかりました。シリアライゼーションにはプロパティセッターは必要ありません。ただし、プロパティにセッターがない場合、XMLはオブジェクトに逆シリアル化しません。宿題が終わりました。
ryadavilli

1
@ryadavilliうんXmlSerializer、それは実装の制限に過ぎず、パブリックセッターメソッドに依存しています。DataContractSerializerその意味ではもう少し賢いです(おそらく、反射を使用してフィールドを舞台裏に設定します)。
James

10

MSDNドキュメントの「XMLシリアル化の概要」を参照してください。特に、それは言う:

シリアル化できるアイテム

次の項目は、XmlSerializerクラスを使用してシリアル化できます。

Public read/write properties and fields of public classes.

Classes that implement ICollection or IEnumerable.

注意:

Only collections are serialized, not public properties.
XmlElement objects.

XmlNode objects.

DataSet objects.

また、「XML-Serializableクラスにパラメーターのないコンストラクターが必要な理由」も参照してください。


また、IXmlSerializable

XMLシリアライザーによってシリアル化できる上記の型に加えて、IXmlSerializableインターフェイスを実装する任意の型をシリアル化および逆シリアル化できます。特に、これはXElementおよびXDocumentタイプをシリアル化できることを意味します。

IXmlSerializableインターフェイス」を参照してください。


6

制限XMLSerializer-セッターのないプロパティはシリアル化できません。

ただしDataContractSerializer、シリアル化に使用できますprivate setter properties-

[DataMember]
public string Id
{
    get
    {
         return Guid.NewGuid().ToString();
    }
    private set {}
}

プロパティはxml属性としてシリアル化されることになっています(元の投稿を参照)。コード(DataMember属性)はxml-elementを生成します。私が知る限り、プロパティを要素ではなく属性に変換するようにDataContractSerializerに指示する(クリーンな)方法はありません。DataContractSerializerは優れていますが、常にこの制限に留意する必要があります。
sth_Weird 2016

2

プライベートセッターが必要で、オブジェクトをシリアル化可能/逆シリアル化可能にし、ISerializableを実装し、MyObject(SerializationInfo info、StreamingContext context)のようなコンストラクターを作成する場合。例はここに発見されました


0

シリアル化属性は、オブジェクトをシリアル化および逆シリアル化するために使用されます。XmlSerializerは、セッターを持たないプロパティをシリアル化する必要がないと想定します。オブジェクトのインスタンスを作成する必要があるため、setterを使用して文字列をオブジェクトに逆シリアル化し、setterを使用してプロパティ値を設定します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.