XmlSerializer strange thing
sorry for my English. I have the strange thing with XmlSerializer. This is my code
[Serializable]
public class Radio
{
public bool hasSubWoofers;
public double[] stationPresets;
[XmlIgnoreAttribute]
public string radioId = "X-3454";
}
[Serializable]
public class Car
{
public Radio radio = new Radio();
public int speed;
}
[Serializable]
public class JamesBondCar : Car
{
public bool canFly;
public bool canSubmerge;
private string flag = "string flag";
}
class JamesBondCar has the private member 'flag' and during serialization XmlSerializer shouldn't serialize it. In XML I'm looking it. The is NO 'flag' field:
<JamesBondCar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<radio>
<hasSubWoofers>true</hasSubWoofers>
<stationPresets>
<double>192.3</double>
<double>45.2</double>
<double>456.3</double>
</stationPresets>
</radio>
<speed>342</speed>
<canFly>true</canFly>
<canSubmerge>false</canSubmerge>
</JamesBondCar>
but, this is main function:
JamesBondCar bond = new JamesBondCar();
开发者_运维百科 bond.canFly = true;
bond.canSubmerge = false;
bond.speed = 342;
bond.radio.hasSubWoofers = true;
bond.radio.stationPresets = new double[] { 192.3, 45.2, 456.3 };
bond.radio.radioId = "Y-3424";
FileStream fs = new FileStream("car.xml", FileMode.Create, FileAccess.Write);
XmlSerializer serializer = new XmlSerializer(typeof(JamesBondCar));
serializer.Serialize(fs, bond);
fs.Close();
FileStream fs2 = new FileStream("car.xml", FileMode.Open, FileAccess.Read);
JamesBondCar jcar = (JamesBondCar)serializer.Deserialize(fs2);
after serialization in debugging I can se in the jcar instanse 'flag' field, that has "string flag" value. How is it possible? XML hasn't got this value.
Any private member fields that have default values like this will be initialized with these default values when the object is constructed (i.e. when the object constructor is called).
Different serializers have different rules; XmlSerializer
happens to be one that initializes the object by demanding and using a public parameterless constructor (commonly the "default" constructor added by the C# compiler). This also has the effect of running all the field initializers (such as private string flag = "string flag";
), which are (at the IL level) part of the constructor.
By contrast, something like DataContractSerializer
doesn't run the constructor; it doesn't run any constructor (there are hooks to do this... it isn't very interesting). This means it relies on the serialized data (and any serialization callbacks - note that XmlSerializer
doesn't support serialization callbacks).
Other serializers may allow you to choose which approach to take.
If you want to skip the constructor and work with non-public data, then DataContractSerializer
can do that, but offers much less control over the xml. If you use XmlSerializer
you need to follow the rules it defines.
精彩评论