c# - Xml 反序列化附加到列表

标签 c# properties xml-serialization xmlserializer

我正在尝试反序列化 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>

最佳答案

基本上,这就是 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;}

(如果你明白我的意思的话)

关于c# - Xml 反序列化附加到列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13046474/

相关文章:

c# - 选择一个不在 LINQ 中的 Group By 子句中的字段

c#:拥有纯公共(public)属性(property)有什么意义

java - 属性文件点分隔的键名

java - 符号已定义。使用 JAXB 属性解决冲突

java - Jibx - 如何使用值和属性解码/编码标签?

c# - 在 Visual Studio 中调试时出现底层连接已关闭错误

c# - 如何为 DotNetOpenAuth 编写 VB 或 C# GUI 客户端?

c# - 无法从 token 类型 'StartObject' 获取 XML 字符串值

matlab - 您可以在 MATLAB 类的默认值中嵌套匿名函数吗?

c# - 从数据创建的 XML 结构中面临的问题