You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C# XmlSerializer反序列化后NonSerialized字段仍有正确值?

关于XmlSerializer反序列化后[NonSerialized]字段保留初始值的疑问

标记了[NonSerialized]的member3未被序列化到XML文件,设为私有后同样不会被序列化,但反序列化后控制台却能输出其值为true,请问原因是什么?

示例代码

public class Test
{
    public static void Main()
    {
        SerializableTestObject testObject = new SerializableTestObject();

        Stream stream = File.Open("data.xml", FileMode.Create);

        XmlSerializer xmlSerializer = new XmlSerializer(typeof(SerializableTestObject));
        xmlSerializer.Serialize(stream, testObject);

        stream.Close();

        testObject = null;

        stream = File.Open("data.xml", FileMode.Open);
        testObject = xmlSerializer.Deserialize(stream) as SerializableTestObject;

        stream.Close();
        testObject?.Print();
    }
}

[Serializable]
public class SerializableTestObject
{
    public int member1;
    public string member2;
    [NonSerialized] 
        bool member3;

    public SerializableTestObject()
    {
        member1 = 24;
        member2 = "Hello World";
        member3 = true;
    }

    public void Print()
    {
        Console.WriteLine($"member1: {member1}");
        Console.WriteLine($"member2: {member2}");
        Console.WriteLine($"member3: {member3}");
        Console.Read();
    }
}

控制台输出

member1: 24
member2: Hello World
member3: True


原因解析

这是因为XmlSerializer的反序列化逻辑是:先调用类的无参构造函数创建对象实例,之后再把XML中存储的序列化字段/属性值,赋值给对应的成员。

你的SerializableTestObject类的无参构造函数里,已经明确把member3初始化为true了。由于member3是私有字段(代码中未加访问修饰符,类内默认私有),XmlSerializer默认不会序列化私有成员;而[NonSerialized]特性其实对XmlSerializer无效——它是给二进制序列化、DataContractSerializer这类序列化器用的。

综上,XML文件里根本没有member3的数据,反序列化时自然不会覆盖它在构造函数中被赋予的初始值,所以最终输出的就是true。

额外补充:[Serializable]特性对XmlSerializer也没有作用,它只关注公共字段/属性,若要忽略公共成员,应该用[XmlIgnore]特性。

内容的提问来源于stack exchange,提问作者Nina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 18:35:40