我想知道如何忽略使用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);
}
}
}
答案 0 :(得分:3)
我怀疑你实际上是在尝试解决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。
答案 1 :(得分:2)
更好的解决方案是使用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());
}