Why are properties without a setter not serialized

I have a serializable class and one of the properties in my class generates a Guid in the getter. The property implements no setter and is ignores during serialization. Why is that and do I always have to implement a setter in order for my property to be serialized.

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

I tried implementing an empty setter and it got serialized correctly.

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

Update:

Can you point out how should I define properties whose values never change or ones that the value for is generated internally?


Solution 1:

It's a limitation of XmlSerializer it doesn't serialize read-only properties, what you have done in your second example is essentially the hack to get it to serialize, however, it's useless if you need it to deserialize later.

Alternatively you could switch to using DataContractSerializer, it's more flexible.

Solution 2:

See "Introducing XML Serialization" in the MSDN documentation. Among other things, it says:

Items That Can Be Serialized

The following items can be serialized using the XmlSerializer class:

Public read/write properties and fields of public classes.

Classes that implement ICollection or IEnumerable.

Note:

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

XmlNode objects.

DataSet objects.

Also, see "Why XML-Serializable class need a parameterless constructor"


Also, IXmlSerializable

In addition to the above types which can be serialized by the XML Serializer, any type which implements the IXmlSerializable interface can be serialized and deserialized. In particular, this means that the XElement and XDocument types can be serialized.

See "IXmlSerializable Interface".

Solution 3:

Limitation of XMLSerializer - Properties without setter can't be serialized.

But you can use DataContractSerializer to serialize private setter properties -

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

Solution 4:

if you want to have private setters, and have the object be serializable/deserializable, impliment ISerializable, and create a constructor like MyObject(SerializationInfo info, StreamingContext context). An example is found here.