【问题标题】:Different ways to add and print keys/values to a dictionary in C#?在 C# 中向字典添加和打印键/值的不同方法?
【发布时间】:2014-01-15 05:59:02
【问题描述】:

我找不到关于这个主题的相关主题,所以我决定提出一个新问题。我在C#Dictionary 课程中迈出了第一步,我有几个基本问​​题。首先,这有什么区别:

Dictionary<int, string> dict = new Dictionary<int, string>();

    dict[1] = "hello";

还有这个(如果有的话):

Dictionary<int, string> dict = new Dictionary<int, string>();

    dict.Add(1, "hello");

我的第二个问题是:有没有办法在同一行添加多个条目(如果我可以这样调用一对键和值)。类似于int a, b, c;,而不是int a; int b; int c;。还是只能将它们添加到多行:

dict.Add(1, "hello");
dict.Add(2, "hey");

关于字典的输出,我的最后一个问题是,是否有一种“更好”的方式来打印字典,而不是那样做:

foreach (KeyValuePair<int, string> pair in dict)
    {
        Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
    }

我的意思是“更好”,即打字速度更快、执行速度更快。 (我知道它也适用于var,而不是KeyValuePair&lt;&gt;

【问题讨论】:

  • 不要太担心打字。 Visual Studio 可以“垂直”选择文本(通过按住 SHIFT ALT),这在需要键入/编辑许多几乎相同的行等情况下非常方便。

标签: c# dictionary


【解决方案1】:

1.这个:dict[1] = "hello" 和这个:dict.Add(1, "hello") 有什么区别?

是的,使用 Add[] 索引器属性是有区别的。

您可以多次拨打dict[1] = "hello";,但您只能拨打一次dict.Add(1, "hello");。否则它会抛出ArgumentException已经添加了具有相同键的项目。

2。有没有办法在同一行添加多个条目(如果我可以这样调用一对键和值)。

在创建Dictionary 时,您只能在一行中使用集合初始化语法添加多个项目:

Dictionary<int, StudentName> students = new Dictionary<int, StudentName>()
{
    { 111, new StudentName {FirstName="Sachin", LastName="Karnik", ID=211}},
    { 112, new StudentName {FirstName="Dina", LastName="Salimzianova", ID=317}},
    { 113, new StudentName {FirstName="Andy", LastName="Ruth", ID=198}}
};

但是,无论如何它都会被编译器转换为Add 方法调用:)

阅读How to: Initialize a Dictionary with a Collection Initializer (C# Programming Guide)

3.是否有一种“更好”的方式来打印字典,而不是那样做:

有一种使用单行表达式打印字典的方法,但我不认为它更具可读性,并且无论如何它都会在内部使用foreach 循环,所以也不会更快:

 Console.WriteLine(string.Join(Environment.NewLine, dict.Select(x => string.Format("{0}: {1}", x.Key, x.Value))));

【讨论】:

    【解决方案2】:

    首先,dict[1] = "hello"dict.Add(1, "hello") 有什么区别

    在实践中,没有大的区别。 [] 是一个索引器,实际上它只是在内部调用 Add()。但是,作为索引器,它可以在键已存在于字典中时替换值。

    我的第二个问题是:有没有办法在同一行添加多个条目(如果我可以这样调用一对键和值)

    是的,在创建新实例时,您可以像这样提供初始化程序:

    new Dictionary<int, string> { { 1, "hello" }, { 2, "world" } }
    

    但是,您应该记住,有时多行代码比一行代码更易读。记住其他开发人员正在阅读您的代码(以及 2 周后的您自己)。

    关于字典输出的最后一个问题是,是否有“更好”的方式来打印字典。 ......我的意思是“更好”,即打字速度更快,执行速度更快。 (我知道它也适用于var,而不是KeyValuePair&lt;&gt;

    • 同样,您不应该因为代码行数而牺牲可读性。你的代码很好,没有必要让它变得“更好”。
    • 一个非常重要的规则:do not optimize prematurely,即不要关心性能,除非您真的有性能问题。
    • var 对性能完全没有影响。

    【讨论】:

    • dict[1] = "Hello" 将覆盖字典中具有相同键的元素,而在这种情况下使用 Add 将引发异常。所以,不,两者不一样。 (我没有投反对票……)
    • 反对者是否愿意发表评论?我们随时为您提供帮助,为初学者提供合理详尽的答案,而不是对一些极端情况的遗漏或简化投反对票。
    • @elgonzo 这正是我几分钟前添加到我的答案中的内容。
    • @elgonzo 所以,如果你是反对者,请随时修正你的投票,或者说明还有什么问题。
    • @Ondreij,我没有投反对票,所以我不能把它拿走;对于那个很抱歉。我仍然为你的回答投了赞成票,因为它的价值......
    【解决方案3】:

    前两个sn-ps等价是key不存在于字典中,可以在documentation中找到:

    与指定键关联的值。如果没有找到指定的键,get 操作会抛出 KeyNotFoundException,而 set 操作会使用指定的键创建一个新元素。

    如果密钥存在,Add 将抛出:

    相反,如果具有指定键的值已存在,则 Add 方法会引发异常。

    第二个问题回答here

    Dictionary<int, StudentName> students = new Dictionary<int, StudentName>()
    {
        { 111, new StudentName {FirstName="Sachin", LastName="Karnik", ID=211}},
        { 112, new StudentName {FirstName="Dina", LastName="Salimzianova", ID=317}},
        { 113, new StudentName {FirstName="Andy", LastName="Ruth", ID=198}}
    };
    

    最后一个问题是主观的,尽管使用var,它可以比你的sn-p简单一点:

    foreach (var entry in dictionary)
        Console.WriteLine("[{0} {1}]", entry.Key, entry.Value); 
    

    【讨论】:

      【解决方案4】:

      问:this: dict[1] = "hello" 和 this: dict.Add(1, "hello") 有什么区别?

      Add 和 dict[something] 背后的逻辑是一样的。

      如果您查看 Dictionary 类源代码,您会发现它使用相同的 Insert 方法来添加条目:

          public TValue this[TKey key] {
              get {
                  // skipped
              }
              set {
                  Insert(key, value, false);
              }
          }
      
          public void Add(TKey key, TValue value) {
              Insert(key, value, true);
          }
      

      它的工作方式相同,只是您只能使用相同的键调用 Add 一次。

      问:是否有一种“更好”的方式来打印字典,而不是那样做

      你可以使用:

              var dict = new Dictionary<int, string>()
              {
                  { 1, "asd" },
                  { 2, "zxc" },
                  { 3, "qwe" }
              };
      

      问:有没有办法在同一行添加多个条目(如果我可以这样调用一对键和值)。

      您可以使用简化的语法:

              foreach (var pair in dict)
              {
                  Console.WriteLine(pair);
              }
      

      输出是:

      [1, asd]
      [2, zxc]
      [3, qwe]
      

      【讨论】:

      • 嗯?它们实际上非常不同:Add 创建并且只会添加一次相同的条目而不会出错。按索引访问条目根本不会创建条目,但如果条目已经存在,您可以连续使用它一千次 - 它会一次又一次地覆盖它的值。
      • @ThomasWeller,我提到过。
      • @ThomasWeller 按索引访问条目创建具有给定键的条目(如果它不存在)。
      【解决方案5】:

      dict[1] = "hello";dict.Add(1, "hello"); 之间的一个关键区别是,如果具有该键的项目已经存在,dict.Add() 将抛出 ArgumentException,而索引器将简单地覆盖现有项目。在我自己尝试之前,我认为 C# 没有这种行为。

      关于您的第二个问题,请参阅此 SO question 了解更多详情。构建字典后,您不能使用内置方法一次添加多个项目。其他答案为您提供了一次构建包含多个项目的字典的方法。

      对于第三个问题,您正在尽其所能地做到最好/可读性强;如果你觉得你会经常这样做,你可能想创建一个扩展方法:

      public static class ExtensionMethods
      {
          public static void PrintDictionary<TKey, TValue>(this Dictionary<TKey, TValue> dictionary)
          {
              foreach(var kvp in dictionary)
              {
                  Console.WriteLine("{0}, {1}", kvp.Key, kvp.Value);
              }
          }
      }
      

      然后您可以简单地调用dict.PrintDictionary() 并获得您想要的输出。

      【讨论】:

      • 是的,没错。
      • 就像 Ondreij 的回答一样,我也不理解负面反馈。无论如何,我赞成正确答案...
      猜你喜欢
      • 1970-01-01
      • 2015-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-29
      • 2020-06-10
      • 1970-01-01
      • 2021-08-14
      相关资源
      最近更新 更多