将文本文件转换为对象字典

时间:2016-03-10 20:42:33

标签: c# dictionary

我有以下课程:

class Car
{ 
    public Make{get; set;}
    public Model{get; set;}
    public Year{get; set;}
    public Color{get; set;}

    public Car(string make, string model, string year, string color)
    {
        this.Make= make;
        this.Model= model;
        this.Year= year;
        this.Color= color;
    }
} 

我有以下文本文件“Carlist.txt”

Id,Make,Model,Year,Color
0,Toyoa,Corola,2000,Blue
1,Honda,Civic,2005,Red

我想要一份表格字典:

Dictionary<string, Car>

这是我的代码,用于读取文本文件并将元素解析为字典,但我无法使其工作:

Dictionary<string, Car> result =
        File.ReadLines("Carlist.txt")
            .Select(line => line.Split(','))
            .ToDictionary(split => split[0], 
                          new Car(split => split[1], 
                                  split => split[2], 
                                  split => split[3], 
                                  split => split[4]));

我做错了什么?我一直在 new Car(

)中的每个拆分元素上收到以下错误
  

错误CS1660无法将lambda表达式转换为'string'类型,因为它不是委托类型

更新

这是我当前的代码,带有自动增量键(变量i ):

int i = 0;
Dictionary<int, Car> result =
          File.ReadLines(path + "Carlist.txt")
              .Select(line => line.Split(','))
              .Where(split => split[0] != "Make")
              .ToDictionary(split => i++, 
                            split => new Car(split[0], 
                                             split[1], 
                                             split[2], 
                                             split[3]));

因此我的文本文件现在看起来像这样:

Make,Model,Year,Color
Toyoa,Corola,2000,Blue
Honda,Civic,2005,Red

3 个答案:

答案 0 :(得分:2)

strings返回split数组。然后,string每个字符串为您提供另一个string数组。 int不是Dictionary<string, Car> result = File.ReadLines("Carlist.txt") .Select(line => line.Split(',')) .ToDictionary(split => int.Parse(split[0]), split => new Car(split[1], split[2], split[3], split[4])); ,因此您必须对其进行解析。你的第二个lambda也搞砸了。类似的东西:

exec

需要注意的一点是,如果第一个元素无法解析为整数(如果您的文件确实包含这些标题,则不会),这将失败。因此,您需要跳过第一行和/或添加一些错误处理。

答案 1 :(得分:2)

您需要解决几个问题。

首先,ToDictionary方法的每个参数都是一个委托,其语法是:

.ToDictionary(split => int.Parse(split[0]), 
  split => new Car(split[1], split[2], split[3], split[4]));

与尝试将委托传递给Car构造函数中的每个参数(与原始代码中一样)相反。

第二个是您将阅读标题行并创建一个标题为值的Car,您可能希望将其排除在外,一种方法是将其添加到ToDictionary上方:

  .Where( split => split[0] != "Id" )

这是一个应该做你想要的版本

var result = File.ReadLines("Carlist.txt")
        .Select(line => line.Split(','))
        .Where( split => split[0] != "Id" )
        .ToDictionary(split => int.Parse(split[0]), split => new Car(split[1], split[2], split[3], split[4]));

答案 2 :(得分:1)

对于那些来这里寻找CSV反序列化的人:

读取CSV和拆分昏迷的方法适用于许多场景,但在许多情况下也会失败。例如,包含昏迷的CSV字段,带引号的字段或带有转义引用的字段。这些都是非常常见的standard和有效的CSV字段,例如Excel。

使用完全支持CSV的库既简单又兼容。一个这样的库是CsvHelper。如果您需要手动控制,它支持各种映射,但在op描述的情况下,它很简单:

public class Car
{
    public string Make { get; set;}
    public string Model { get; set; }
    public int Year { get; set; }
    public string Color { get; set; }
}

void Main()
{
    List<Car> cars;
    using (var fileReader = File.OpenText("Cars.txt"))
    {
        using (var csv = new CsvHelper.CsvReader(fileReader))
        {
            cars = csv.GetRecords<Car>().ToList();
        }
    }
    // cars now contains a list of Car-objects read from CSV.
    // Header fields (first line of CSV) has been automatically matched to property names.  

    // Set up the dictionary. Note that the key must be unique.
    var carDict = cars.ToDictionary(c => c.Make);        
}