如何忽略特定列表< T>项目序列容器类时 [英] How to ignore a specific List<T> item when serializing a container class

查看:111
本文介绍了如何忽略特定列表< T>项目序列容器类时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何忽略的特定项/指数的一个列表与LT的; T> 使用正在连载<$ C $ 。C>的XmlSerializer



例如,请考虑以下列表:

  ... 
名单,LT; INT>收集=新的List< INT>(){0,1,2};
...



我想什么来实现序列化时,上方列表< INT> 的XmlSerializer ,我想在 0 被忽略从被序列化,所以期望的结果是:

  ... 
<收缴>
< INT> 1 LT; / INT>
将; INT→2&下; / INT>
< /收藏> //正如你所看到的 - 没有< INT> 0℃; / INT>值。
...



感谢。



更新



下面的代码是我的问题的一个具体的例子:

  [Serializable接口] 
公共类球
{
私人静态只读XmlSerializer的串行器=新的XmlSerializer(typeof运算(球));

公共球()
{
//值1,我不希望被序列化的默认值。
点=新的List< INT>(){1};
IsEnabled = FALSE;
}

公开名单< INT>点{搞定;组; }
公共BOOL IsEnabled {搞定;组; }

公共无效保存()
{$ B $使用B(StreamWriter的作家=新的StreamWriter(文件名))
{
Serializer.Serialize(作家,这);
}
}

公装球量()
{
使用(StreamReader的读者=新的StreamReader(文件名))
{
返回(球)Serializer.Deserialize(读卡器);
}
}
}


解决方案

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



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

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

公共BOOL IsEnabled {搞定;组; }

[XmlIgnore]
公开名单< INT>点{搞定;组; }

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

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

公共静态类ListExtensions
{
公共静态列表< T>初始化< T>(列表< T>列表中,T []值)(!列表= NULL)
{
如果(价值== NULL)
{
如果
list.Clear();
}
,否则
{
(名单=名单??新的List< T>(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.

这篇关于如何忽略特定列表&LT; T&GT;项目序列容器类时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆