C#中的多维关联数组

本文关键字:关联 数组 | 更新日期: 2023-09-27 18:23:55

我对C#完全陌生。我是一名PHP程序员。所以请耐心等待。

我有一个包含以下内容的XML:

<setting name="event1" color="white" align="center" />
<setting name="event2" color="red" align="left" />

我已经知道如何使用XmlReaderGetAttribute获取信息,但我完全不知道如何将其存储到数组中。我想要的最后一个数组是这样的:

Array
(
    [event1] => Array
    (
        [color] => white
        [align] => center
    )
    [event2] => Array
    (
        [color] => red
        [align] => left
    )
)

因此,如果我想访问一个名为"设置"的数组中的信息,我会使用:

settings["event1"]["color"] = "white";

我该如何在C#中执行这样的操作?请记住,我对C#完全陌生。

-----编辑

我尝试添加一个类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace xSplit_Panel_Writer
{
    class Settings
    {
        public string Color { get; set; }
        public string Align { get; set; }
    }
}

但我在实际剧本中遇到了问题。。。

        using (XmlReader reader = XmlReader.Create("data/config.xml"))
        {
            while (reader.Read())
            {
                if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "setting"))
                {
                    var settings = new Dictionary<string, Settings>();
                    settings.Add(reader.Name, reader);
                }
            }
        }

我得到以下错误:

Error   1   The best overloaded method match for 'System.Collections.Generic.Dictionary<string,xSplit_Panel_Writer.Settings>.Add(string, xSplit_Panel_Writer.Settings)' has some invalid arguments  C:'Users'Jaxel'documents'visual studio 2010'Projects'xSplit Panel Writer'xSplit Panel Writer'MainForm.cs    31  25  xSplit Panel Writer
Error   2   Argument 2: cannot convert from 'System.Xml.XmlReader' to 'xSplit_Panel_Writer.Settings'    C:'Users'Jaxel'documents'visual studio 2010'Projects'xSplit Panel Writer'xSplit Panel Writer'MainForm.cs    31  51  xSplit Panel Writer

C#中的多维关联数组

如果XML中的属性是静态的,我会选择创建一个类来封装数据。这将为您提供一个强类型对象,该对象具有可以针对其进行编码的属性,从而获得完整的编译时支持、智能感知等。

class Setting
{
    public string Name { get; set; }
    public string Color { get; set; }
    public string Align { get; set; }
}

然后,您可以使用数据填充此类的实例,创建它们的列表,甚至可以使用Name作为关键字将它们加载到字典中。

var setting = LoadSettingFromXml();
var settings = new Dictionary<string, Setting>();
settings.Add(setting.Name, setting); 
// elsewhere
settings["event1"].Color = "blue";

您可以从那里学习如何使用Linq-to-Xml将Xml读取到这些对象中,并进一步读取到您喜欢的集合类型中。


一个完整的代码示例。给定上面定义的类和有效的XML片段

string xml = @" <settings>
                    <setting name=""event1"" color=""white"" align=""center"" /> 
                    <setting name=""event2"" color=""red"" align=""left"" />
                </settings>";

您可以使用Linq-to-Xml将文档解析为一系列对象。

// can also use XDocument.Load(...) to load from a file or stream.
var document = System.Xml.Linq.XDocument.Parse(xml);
var settingsList = (from element in document.Root.Elements("setting")
                    select new Setting
                    {
                        Name = element.Attribute("name").Value,
                        Color = element.Attribute("color").Value,
                        Align = element.Attribute("align").Value
                    }).ToList();

您可以将其进一步转换为词典。首先,显示使用循环创建字典"漫长的路"。

var settingsDictionary = new Dictionary<string, Setting>();
foreach (var setting in settingsList)
{
    settingsDictionary.Add(setting.Name, setting);
}

但是您也可以使用Linq将序列转换为字典,而不需要显式循环。

var settingsDictionary = settingsList.ToDictionary(s => s.Name, s => s);

作为引用,Linq代码需要.NET 3.5+(C#3.0+,Visual Studio 2008+版本),以及对System.Core.dll、System.Xml.Linq.dll的引用,并使用System.Linq和System.Xml.Lin q的指令。默认情况下,在Visual Studio中创建的大多数新解决方案中将引用dll。

您需要嵌套的Dictionary实例:

var outer = new Dictionary<String, Dictionary<String, String>>();
var inner = new Dictionary<String, String>();
inner["align"] = "left";
// ...
outer["Event1"] = inner;

我认为您最好使用XDocument而不是XmlReader。这样,您就可以加载XML,然后立即访问它,几乎可以按照您想要的方式:

XElement settingsParent = …;
var event1Color = settingsParent.Elements()
                                .Single(s => s.Attribute("name").Value == "event1")
                                .Attribute("color").Value;

当然,它比使用关联数组的代码要详细得多,但另一方面,您不必编写任何转换代码。