【问题标题】:How to initialize a dictionary containing lists of dictionaries?如何初始化包含字典列表的字典?
【发布时间】:2011-09-18 09:46:52
【问题描述】:

我开始在 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;

但是我想一次将上面的三个记录插入到 people 中。我一直被语法错误困扰。

有人可以帮我解决吗?

编辑:

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

【问题讨论】:

  • 您的主要问题是您想用 C# 编写 python。 C# 主要是静态类型的,你应该利用它。您可以使用 dynamic 和类似 expando 对象的东西来获得类似于动态类型语言的行为。但是惯用的 C# 使用静态类型与定义您的成员而不是字典的类。你的外部字典很好,你的内部字典很丑,因为它应该是一个类。

标签: c# dictionary


【解决方案1】:

您可以使用dictionary initializes。不如 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&lt;string, Dictionary&lt;string, double&gt;&gt; 而不是 Dictionary&lt;string, Dictionary&lt;string, double&gt;[]&gt;。

同样使用这种结构可能会有点 PITA 并损害代码的可读性和编译时类型安全。

在 .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();

当然要注意,使用集合不会像哈希表查找那样快,但根据您在性能方面的需求,您也可以接受。

【讨论】:

  • +1 我可以建议使用类型别名,例如using MyDict = System.Collections.Generic.Dictionary&lt;string, double&gt;;吗?
  • @Ani,是的,你可以。实际上我建议使用Person 类而不是字典。
  • 我可以建议不要使用类型别名吗?我更喜欢using System.Collections.Generic。
【解决方案2】:

恕我直言,在 c# 中这样做更优雅,为了避免使用字典,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 to get the person you want

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

【讨论】:

  • 为什么“避免...字典”类是一个理想的目标?
  • 因为 OP 的问题不在于键值关系
  • 嵌套字典天生就是一件坏事吗?
【解决方案3】:

您可以轻松做到这一点:

 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}}}
 };

您最好使用类型化的人,或者使用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 }}
     };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    • 2020-04-09
    相关资源
    最近更新 更多