XmlSerializer奇怪的事情

时间:2011-08-04 08:11:37

标签: c# .net

抱歉我的英语。 我对XmlSerializer很奇怪。这是我的代码

[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";
}

类JamesBondCar具有私有成员'flag',在序列化期间,XmlSerializer不应该序列化它。在XML中,我正在寻找它。是'标志'字段:

<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>

但是,这是主要功能:

            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);
在调试中序列化之后,我可以在jcar instanse'flag'字段中找到“string flag”值。这怎么可能? XML没有这个价值。

2 个答案:

答案 0 :(得分:6)

在构造对象时(即调用对象构造函数时),将使用这些默认值初始化任何具有此类默认值的私有成员字段。

答案 1 :(得分:2)

不同的序列化程序有不同的规则; XmlSerializer碰巧是通过要求和使用公共无参数构造函数(通常是C#编译器添加的“默认”构造函数)来初始化对象的。这还具有运行所有字段初始值设定项(例如private string flag = "string flag";)的效果,它们是(在IL级别)构造函数的一部分。

相比之下,像DataContractSerializer 这样的东西不会 运行构造函数;它不运行任何构造函数(有钩子来做这个...它不是很有趣)。这意味着它依赖于序列化数据(以及任何序列化回调 - 请注意XmlSerializer支持序列化回调)。

其他序列化程序可能允许您选择采用哪种方法。

如果你想跳过构造函数并使用非公共数据,那么DataContractSerializer可以做到这一点,但对xml的控制要少得多。如果您使用XmlSerializer,则需要遵循其定义的规则。