【问题标题】:Prevent XmlSerializer from auto instantiating List's on Deserialize防止 XmlSerializer 在反序列化时自动实例化列表
【发布时间】:2015-11-06 04:23:02
【问题描述】:

假设我有这个示例类:

public class MyClass
{
    public List<int> ListTest { get; set; }
    public string StringTest { get; set; }
    public int IntTest { get; set; }
}

还有这段代码:

string xmlStr = "<MyClass><StringTest>String</StringTest></MyClass>";
XElement xml = XElement.Parse(xmlStr);
XmlSerializer ser = new XmlSerializer(typeof(MyClass));
using (XmlReader reader = xml.CreateReader())
{
    var res = ser.Deserialize(reader);
}

反序列化完成后,res 的值为:
ListTest -> Count = 0 (NOT null) 的空列表。
StringTest ->符合预期的“字符串”
IntTest -> 符合预期的 0(整数的默认值)。

我希望序列化程序与 List 的行为相同(default(List&lt;T&gt;) 为空),而不是实例化它们。

我怎样才能完成这样的事情?
顺便说一句,我必须使用XmlSerializer。

【问题讨论】:

    标签: c# deserialization xmlserializer


    【解决方案1】:

    您可以使用备份属性将属性序列化/反序列化为数组:

    public class MyClass
    {
        [XmlIgnore]
        public List<int> ListTest { get; set; }
        [XmlElement("ListTest")]
        public int[] _listTest
        {
            get { return ListTest?.ToArray(); }
            set { ListTest = value == null ? null : new List<int>(value); }
        }
        ...
    }
    

    【讨论】:

    • 将ListTest设为私有并将其用作支持字段会更好。
    • @UğurAldanmaz,有are problems 用XmlSerializer 序列化private 成员。至于List&lt;T&gt; 类型建议的后场,暴露T[] 属性(在getter 中有list.ToArray()?)很昂贵,我一般不会这样做。这里的想法是只调整序列化,保持public List&lt;T&gt;属性不变,因为我不知道它的使用场景(可能很大,可能经常调用属性,可能经常设置,等等)
    • 我建议将其设为私有,因为它具有[XmlIgnore] 属性,因此不会被序列化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-23
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多