C# C如何根据LINQ查询中的字符串数组声明新的Dictionary对象

C# C如何根据LINQ查询中的字符串数组声明新的Dictionary对象,c#,linq,C#,Linq,我有一些这样的代码: using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; class Program { static void Main(string[] args) { string xml = @"<Root> <Report1> <Row> <Field1>

我有一些这样的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

class Program
{
    static void Main(string[] args)
    {
        string xml = @"<Root>
  <Report1>
    <Row>
      <Field1>data1-1</Field1>
      <Field2>data1-2</Field2>
      <!-- many more fields -->
    </Row>
    <Row>
      <Field1>data2-1</Field1>
      <Field2>data2-2</Field2>
      <!-- many more fields -->
    </Row>
  </Report1>
</Root>";

        XDocument doc = XDocument.Parse(xml);

        var report1 = from report in doc.Root.Elements("Report1").Elements("Row")
                      select new Dictionary<string, string>()
                          {
                              {"Field1", report.Elements("Field1").First().Value},
                              {"Field2", report.Elements("Field2").First().Value}
                          };

        var i = 1;
        foreach (Dictionary<string, string> dict in report1)
        {
            Console.WriteLine(String.Format("Row{0}: ", i));
            Console.WriteLine("  Field1: {0}", dict["Field1"]);
            Console.WriteLine("  Field2: {0}", dict["Field2"]);
            i++;
        }

        Console.ReadLine();
    }
}
是否可以定义一个字符串数组或其他数据结构,我可以用它来声明这些字典对象?下面是一些愚蠢的伪代码,有助于展示我的想法:

在下面的伪代码中编辑变量fieldNames将是我期望的名称数组,而不是基于xml源字段名称。我将忽略xml源中未在fieldNames数组中显式设置的任何字段名

var report1 = from report in doc.Root.Elements("Report1").Elements("Row")
              select new Dictionary<string, string>()
           {
              foreach (var fieldName in fieldNames)
              {
                  {fieldName, report.Elements(fieldName).First().Value}
              }
           };
使用Enumerable.ToDictionary:

使用Enumerable.ToDictionary:


不要试图在一个集合初始值设定项中完成所有操作

对于类似的内容,我将创建一个单独的方法:

public static Dictionary<string, string> MapReport(XElement report)
{
    var output = new Dictionary<string, string>();
    foreach(var field in report.Elements())
    {
        output.Add(field.Name, ...);
    }
}

不要试图在一个集合初始值设定项中完成所有操作

对于类似的内容,我将创建一个单独的方法:

public static Dictionary<string, string> MapReport(XElement report)
{
    var output = new Dictionary<string, string>();
    foreach(var field in report.Elements())
    {
        output.Add(field.Name, ...);
    }
}

伪代码实际上非常接近您真正能做的。我想你已经准备好了一个单独的fieldNames集合

IEnumerable<string> fieldNames = ...;
XDocument doc = ...;
var report1 = doc.Root.Elements("Report1").Elements("Row")
    .Select(report =>
    {
        var d = new Dictionary<string, string>();
        foreach (var fieldName in fieldNames)
        {
            d.Add(fieldName, report.Elements(fieldName).First().Value);
        }
        return d;
    });

伪代码实际上非常接近您真正能做的。我想你已经准备好了一个单独的fieldNames集合

IEnumerable<string> fieldNames = ...;
XDocument doc = ...;
var report1 = doc.Root.Elements("Report1").Elements("Row")
    .Select(report =>
    {
        var d = new Dictionary<string, string>();
        foreach (var fieldName in fieldNames)
        {
            d.Add(fieldName, report.Elements(fieldName).First().Value);
        }
        return d;
    });

这将为您提供一个类型列表


这将为您提供一个类型列表


OP的代码正在创建一个IEnumerable,您的代码正在创建一个字典。OP的代码正在创建一个IEnumerable,您的代码正在创建一个字典。即使在编辑之后,您希望在报表中显示的字段集是否基于xml内容仍然不完全清楚。@Tar,谢谢我进行了编辑。我要导入的字段不是基于xml源,而是在数组或列表中显式设置的字段。即使在编辑之后,您想要在报表中输入的字段集是否基于xml内容仍然不完全清楚。@Tar,谢谢我的编辑。我要导入的字段不是基于xml源,而是数组或列表中显式设置的字段。+1因为这个答案也有效,只是Thom Smith在发布答案时只快了一分钟。+1因为这个答案也有效,只是Thom Smith在发布答案时只快了一分钟。
var rows = doc.Descendants("Row")
           .Select(r => r.Elements()
                         .ToDictionary(x => x.Name.LocalName, x => x.Value))
           .ToList();
var data = rows[i]["Field1"];