如何忽略特定列表<;T>;项

本文关键字:gt 何忽略 lt 列表 | 更新日期: 2023-09-27 18:22:22

我想知道如何忽略使用XmlSerializer序列化的List<T>的特定项/索引。

例如,考虑以下列表:

...
List<int> collection = new List<int>() {0, 1, 2};
...

我想实现的是,当使用XmlSerializer序列化上述List<int>时,我希望0在序列化时被忽略,因此所需的结果是:

...
<collection>
    <int>1</int>
    <int>2</int>
</collection> // as you can see - there is no <int>0</int> value.
...

谢谢。

更新

以下代码是我的问题的一个具体示例:

[Serializable]
public class Ball
{
    private static readonly XmlSerializer Serializer = new XmlSerializer(typeof(Ball));
    public Ball()
    {
        // value 1 is a default value which I don't want to be serialized.
        Points = new List<int>() { 1 };
        IsEnabled = false;
    }
    public List<int> Points { get; set; }
    public bool IsEnabled { get; set; }
    public void Save()
    {
        using (StreamWriter writer = new StreamWriter(FILENAME))
        {
            Serializer.Serialize(writer, this);
        }
    }
    public Ball Load()
    {
        using (StreamReader reader = new StreamReader(FILENAME))
        {
             return (Ball)Serializer.Deserialize(reader);
        }
    }
}

如何忽略特定列表<;T>;项

我怀疑您实际上是在试图解决XY问题,其中真正的问题是使用XmlSerializer反序列化导致额外项的列表问题中描述的问题:当您序列化和反序列化在构造函数中添加了默认项的集合属性时,默认项会重复,因为反序列化的默认项被添加到最新的默认项中。

这个问题的答案提供了一个解决方法,即将默认集合项的初始化从构造函数中移出。如果这不方便,您可以引入代理数组属性并序列化它,而不是底层集合:

[Serializable]
public class Ball
{
    public Ball()
    {
        Points = new List<int>() { 1 };
        IsEnabled = false;
    }
    public bool IsEnabled { get; set; }
    [XmlIgnore]
    public List<int> Points { get; set; }
    [XmlArray("Points")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public int[] SerializablePoints
    {
        get
        {
            return (Points == null ? null : Points.ToArray());
        }
        set
        {
            Points = ListExtensions.Initialize(Points, value);
        }
    }
}
public static class ListExtensions
{
    public static List<T> Initialize<T>(List<T> list, T[] value)
    {
        if (value == null)
        {
            if (list != null)
                list.Clear();
        }
        else
        {
            (list = list ?? new List<T>(value.Length)).Clear();
            list.AddRange(value);
        }
        return list;
    }
}

有关属性必须是数组的原因的解释,请参阅具有默认代码的集合属性的XML反序列化。

更好的解决方案是使用LINQ查询创建一个新集合,并将其传递给序列化程序,如

List<int> collection = new List<int>(){ 0, 1, 2, 3 };
using (var fs = new StreamWriter("serialized.txt"))
{
    XmlSerializer serializer = new XmlSerializer(collection.GetType());
    serializer.Serialize(fs, collection.Where(x => x != 0).ToList());
}