我正在尝试从xml文件反序列化某些设置。有问题的属性/基础字段是一个名为AlertColors
的字段。我将基础字段初始化为白色,黄色和红色,以确保此类的新实例具有有效的颜色设置。但是当我反序列化时,_colorArgb
最终得到六个值,前三个是初始化值,后三个是从xml文件中读取的值。但属性AlertColors
不会附加到字段,而是更改其元素。为什么我最终得到一个有六种颜色的字段?
以下是代码:
private List<int> _colorArgb = new List<int>(new int[] { Color.White.ToArgb(), Color.Yellow.ToArgb(), Color.Red.ToArgb() });
public List<int> AlertColors
{
get
{
return _colorArgb;
}
set
{
for (int i = 0; i < Math.Min(_colorArgb.Count, value.Count); i++)
{
if (_colorArgb[i] != value[i])
{
HasChanged = true;
}
}
_colorArgb = value;
}
}
public bool Deserialize(string filePath)
{
if (!File.Exists(filePath))
{
Logger.Log("Error while loading the settings. File does not exist.");
return false;
}
FileStream fileStream = null;
try
{
fileStream = new FileStream(filePath, FileMode.Open);
System.Xml.Serialization.XmlSerializerFactory xmlSerializerFactory =
new XmlSerializerFactory();
System.Xml.Serialization.XmlSerializer xmlSerializer =
xmlSerializerFactory.CreateSerializer(typeof(Settings));
Settings deserializedSettings = (Settings)xmlSerializer.Deserialize(fileStream);
GetSettings(deserializedSettings);
Logger.Log("Settings have been loaded successfully from the file " + filePath);
}
catch (IOException iOException)
{
Logger.Log("Error while loading the settings. " + iOException.Message);
return false;
}
catch (ArgumentException argumentException)
{
Logger.Log("Error while loading the settings. " + argumentException.Message);
return false;
}
catch (InvalidOperationException invalidOperationException)
{
Logger.Log("Error while loading the settings. Settings file is not supported." +
invalidOperationException.Message);
return false;
}
finally
{
if (fileStream != null)
fileStream.Close();
FilePath = filePath;
}
return true;
}
protected void GetSettings(Settings settings)
{
AlertColors = settings.AlertColors;
}
我正在反序列化的xml文件的相关部分:
<AlertColors>
<int>-1</int>
<int>-15</int>
<int>-65536</int>
</AlertColors>
答案 0 :(得分:4)
基本上,这就是XmlSerializer
的工作原理。除非列表是null
,否则它永远不会尝试设置值。特别是最的时间,子项列表没有一个setter - 它们是这样的:
private readonly List<Child> children = new List<Child>();
public List<Child> Children { get { return children; } }
(因为大多数人不希望外部呼叫者重新分配列表;他们只是希望他们更改内容。)
因此,XmlSerializer
的运作基本上与(过度简化)相同:
var list = yourObj.SomeList;
foreach({suitable child found in the data})
list.Add({new item});
一个解决方法是使用数组而不是列表;它总是希望将一个数组分配给该对象,因此对于一个数组,它实现更像(过度简化):
var list = new List<SomeType>();
foreach({suitable child found in the data})
list.Add({new item});
yourObj.SomeList = list.ToArray();
但是,对于固定数量的值,更简单的实现可能只是:
public Foo Value1 {get;set;}
public Foo Value2 {get;set;}
public Foo Value3 {get;set;}
(如果你明白我的意思)
答案 1 :(得分:2)
要在不更改数据类型的情况下获得所需结果,可以使用DataContractSerializer(使用System.Runtime.Serialization;)而不是普通的XmlSerializer。它不会调用默认构造函数,因此最终会使用3种颜色而不是6种颜色。
var ser = new DataContractSerializer(typeof(Settings));
var reader = new FileStream(@"c:\SettingsFile.xml", FileMode.Open);
var deserializedSettings = (Settings)ser.ReadObject(reader);