且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何忽略特定列表< T>项目序列容器类时

更新时间:2022-10-31 08:57:44

我怀疑你实际上是试图解决一个 XY问题哪里真正的问题是在问题反序列化清单,XmlSerializer的导致额外的项目描述的:当你序列化和反序列化在构造函数中添加默认项集合属性,默认的项目将复制的,因为反序列化的默认项被添加到最新的默认项



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

  [Serializable接口] 
酒店的公共类球
{
公共球()
{
点=新的List&LT; INT&GT;(){1};
IsEnabled = FALSE;
}

公共BOOL IsEnabled {搞定;组; }

[XmlIgnore]
公开名单&LT; INT&GT;点{搞定;组; }

[XmlArray(点)]
[可浏览(假),EditorBrowsable(EditorBrowsableState.Never),DebuggerBrowsable(DebuggerBrowsableState.Never)
公众诠释[] SerializablePoints
{
得到
{
回报率(点== NULL空:Points.ToArray());
}

{
点= ListExtensions.Initialize(点值);
}
}
}

公共静态类ListExtensions
{
公共静态列表&LT; T&GT;初始化&LT; T&GT;(列表&LT; T&GT;列表中,T []值)(!列表= NULL)
{
如果(价值== NULL)
{
如果
list.Clear();
}
,否则
{
(名单=名单??新的List&LT; T&GT;(value.Length))。清除();
list.AddRange(值);
}
返回列表;
}
}

有关为何属性必须是一个解释阵列的,看到的 XML反序列化集合属性与代码默认


I would like to know how to ignore a specific item/index of a List<T> from being serialized using XmlSerializer.

For example, consider the following list:

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

What I would like to achieve is when serializing the above List<int> using XmlSerializer, I want the 0 to be ignored from being serialized, so the desired result is:

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

Thanks.

UPDATE

The following code is a concrete example of my question:

[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);
        }
    }
}

I suspect you are actually trying to solve an XY problem where the real problem is the one described in the question Deserializing List with XmlSerializer Causing Extra Items: when you serialize and deserialize a collection property that has default items added in the constructor, the default items get duplicated, because the deserialized default items get added to the latest default items.

That answer to that question provides one workaround, namely to move initialization of the default collection entries out of the constructor. If that's not convenient, you can instead introduce a proxy array property and serialize that instead of the underlying collection:

[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;
    }
}

For an explanation of why the property must be an array, see XML Deserialization of collection property with code defaults.