将xml字符串反序列化为对象,我得到缺少列表元素的空列表。为什么它不返回null?

时间:2011-06-20 09:24:14

标签: c# xml-serialization deserialization

public class Warning
{

    public Warning()
    {

    }

    public Warning(String name, List<String> conflictList)
    {
        Name = name;
        ConflictList = conflictList;
    }

    public string Name 
    { 
        get; 
        set; 
    }

    public List<String> ConflictList
    {
        get;
        set; 
    }

    public static Warning ReadXML(string xml)
    {
        Warning warning = null;

        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Warning));
            using (StringReader sr = new StringReader(xml))
            {
                XmlTextReader xtr = new XmlTextReader(sr);
                warning = (Warning)serializer.Deserialize(xtr);
                xtr.Close();
                sr.Close();
            }
        }
        catch
        {
        }

        return warning;
    }

    public void Save(string filename)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Warning));
        using (StreamWriter writer = new StreamWriter(filename))
        {
            serializer.Serialize(writer, this);
            writer.Close();
        }
    }
}

如果我反序列化以下xml字符串,我会返回Name和ConflictList的非空值。这很好,我期待的。

Warning w1 = Warning.ReadXML(
    "<Warning><Name>test warning</Name><ConflictList><string>file1.txt</string></ConflictList></Warning>");

w1.Name返回“测试警告”,w1.ConflictList返回包含文本“file1.txt”的列表

但是,如果我反序列化以下xml字符串,w2.Name将返回null,我理解,但是ConflictList实际上是一个Count为0的列表。我希望它也是null。怎么会?

Warning w2 = Warning.ReadXML("<Warning></Warning>");

我确信在某些情况下,如果xml字符串中不存在该元素,w1.ConflictList可以返回null,但是这种情况何时发生?

1 个答案:

答案 0 :(得分:0)

如果它不在xml中,我也会期望它不管它,但是我也可以重现你所说的,既是“原样”,也是成员[XmlElement(...)]。我猜内部它正在新增列表“以防万一”。

我还尝试使用get和惰性初始值设定项替代语法,即

// note: doesn't work; see answer text
private List<string> conflictList;
public List<String> ConflictList
{
    get { return conflictList ?? (conflictList = new List<string>()); }
}

但即使没有包含冲突数据,它仍会调用此getter。令人讨厌的是*Specified模式只被指定 指定的数据 - 它不会被调用未指定的数据,否则你可以做:

// note: doesn't work; see answer text
[XmlIgnore]
public bool ConflictListSpecified
{
    get { return ConflictList != null; }
    set { if (!value) ConflictList = null; }
}

除此之外,XmlSerializer不支持序列化回调,而且我没有选择。

我已经将它测试回.NET 2.0,它的行为也一样......