c# - 序列化容器类时如何忽略特定的 List<T> 项

标签 c# .net serialization xmlserializer

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

例如,考虑以下列表:

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

我想实现的是序列化上面的List<int>使用 XmlSerializer , 我想要 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);
        }
    }
}

最佳答案

我怀疑你实际上是在尝试解决 XY problem真正的问题是问题中描述的问题 Deserializing List with XmlSerializer Causing Extra Items : 当您序列化和反序列化一个在构造函数中添加了默认项的集合属性时,默认项会重复,因为反序列化的默认项会添加到最新的默认项中。

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

[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 Deserialization of collection property with code defaults .

关于c# - 序列化容器类时如何忽略特定的 List<T> 项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33786527/

相关文章:

java动态判断当前执行的类

c# - 是否可以请求 AWS S3 下载文件?

c# - "not in"的 Lambda 表达式?

.NET Standard 项目构建失败并显示无用消息

C# - 发送邮件失败

带有序列化的 Java 8 Lambda 表达式

类似于eternity的C++对象持久化库

c# - HttpContent.ReadAsStringAsync 导致请求挂起(或其他奇怪的行为)

c# - 如何从 Windows 服务将文件复制到网络位置?

c# - 是否有 ListDictionary 类的通用替代品?