如何初始化一个包含字典列表的字典?

28

我开始学习C#开发,遇到了一个问题。我通常在Python中开发,这种东西很容易实现(至少对我来说),但是我不知道如何在C#中做到这一点:

我想使用泛型集合创建一个包含以下类型字典列表的字典:

{ "alfred",  [ {"age", 20.0}, {"height_cm", 180.1} ],
  "barbara", [ {"age", 18.5}, {"height_cm", 167.3} ],
  "chris",   [ {"age", 39.0}, {"height_cm", 179.0} ]
}

我从以下内容开始:

using System.Collections.Generic;
Dictionary<String, Dictionary<String, double>[]> persons;

但是我想一次性将上述三条记录插入到persons表中,我一直被语法错误困扰。

有没有人能为我提供解决方案?

编辑:

谢谢大家-我没想到在这么短的时间内会收到这么多深思熟虑的答案!你们太棒了!


4
去读读手册吧! :) - bzlm
7
你的主要问题是想在C#中编写Python。C#主要是静态类型的语言,你应该充分利用这一点。你可以使用“dynamic”和类似扩展对象的东西来实现类似动态类型语言的行为。但是,符合C#惯用法的做法是使用定义成员的类来进行静态类型定义,而不是使用字典。你的外部字典没问题,但内部字典很丑陋,因为它应该使用一个类来代替。 - CodesInChaos
3个回答

53

你可以使用字典初始化。虽然不如Python优雅,但是可以胜任:

var persons = new Dictionary<string, Dictionary<string, double>>
{
    { "alfred", new Dictionary<string, double> { { "age", 20.0 }, { "height_cm", 180.1 } } },
    { "barbara", new Dictionary<string, double> { { "age", 18.5 }, { "height_cm", 167.3 } } },
    { "chris", new Dictionary<string, double> { { "age", 39.0 }, { "height_cm", 179.0 } } }
};

然后:

persons["alfred"]["age"];

此外还要注意,您需要使用Dictionary<string,Dictionary<string,double>>而不是Dictionary<string,Dictionary<string,double> []>来构建此结构。
使用这样的结构可能会有点麻烦,并且会影响代码的可读性和编译时类型安全性。
在.NET中,最好使用强类型对象,如下所示:
public class Person
{
    public double Age { get; set; }
    public string Name { get; set; }
    public double HeightCm { get; set; }
}

然后:

var persons = new[]
{
    new Person { Name = "alfred", Age = 20.0, HeightCm = 180.1 },
    new Person { Name = "barbara", Age = 18.5, HeightCm = 180.1 },
    new Person { Name = "chris", Age = 39.0, HeightCm = 179.0 },
};

然后您可以使用LINQ来获取所需的任何信息:

double barbarasAge = 
    (from p in persons
     where p.Name == "barbara"
     select p.Age).First();

当然需要注意的是,使用集合比哈希表查找速度更慢,但根据你在性能方面的需求,你可能可以接受这一点。


2
+1 可以建议使用类型别名,例如using MyDict = System.Collections.Generic.Dictionary <string,double>;吗? - Ani
@Ani,可以的。实际上,我建议使用Person类而不是字典。 - Darin Dimitrov
2
我可以建议不使用类型别名吗?我更喜欢只使用using System.Collections.Generic - CodesInChaos

4
你可以轻松地完成这个任务:
 Dictionary<string, Dictionary<string, double>> dict =  
                       new Dictionary<string,Dictionary<string, double>>() {
     {"alfred",new Dictionary<string,double>() {{"age",20.0},{"height":180.1}}},
     {"barbara",new Dictionary<string,double>() {{"age",18.5},{"height": 167.3}}}
 };

不过,使用类型化的 person 或者 ExpandoObject 来访问字典中的语法更好。

Dictionary<string, Person> dict = new Dictionary<string,Person>() {
         {"alfred",new Person { age=20.0 ,height=180.1 }},
         {"barbara",new Person { age=18.5,height=167.3 }}
     };

2

在我看来,在C#中更优雅的做法是避免使用Dictionary,C#有比这更好的选项,

是创建一个(或结构体),例如Person

public class Person 
{
    public Person() { }

    public string Name {get;set;}
    public int Age {get;set;}
    public double Height {get;set;}
}

将这些对象放入实现IEnumerable的通用列表或集合中。

public List<Person>;

使用Linq来获取您所需的人员信息

var personToLookfor =
    from p in people
    where p.Name == "somename"
    select p;

2
避免使用“字典”类是一个值得追求的目标,为什么呢? - Cos Callis
因为OP的问题不涉及键值关系。 - Caspar Kleijne
1
嵌套字典本质上是一件坏事吗? - Kyle Baran
字典比完整的类稍微快一些,使用的内存也更少。 - adamhill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接