从只有一个键的C#字典中获取唯一键的首选方法?

从只有一个键的C#字典中获取唯一键的首选方法?,c#,C#,我正在编写一个代码块,将数据打印到字典中,并尝试根据键的数量对显示进行不同的格式化 我希望有如下输出: 如果字典中没有键: 字典里什么也没有 如果字典中有一个键: 条目{key}的值为{value} 如果字典中有多个键: 词典中有以下条目: {Key}:{Value} {Key}:{Value} {Key}:{Value} 等等 我的代码类似于: Dictionary<string, string> dict = new Dictionary<string,str

我正在编写一个代码块,将数据打印到字典中,并尝试根据键的数量对显示进行不同的格式化

我希望有如下输出:

  • 如果字典中没有键:

    字典里什么也没有

  • 如果字典中有一个键:

    条目{key}的值为{value}

  • 如果字典中有多个键:

    词典中有以下条目:

    • {Key}:{Value}
    • {Key}:{Value}
    • {Key}:{Value}
等等

我的代码类似于:

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

//code that populates the dictionary

string output;
if(dict.Count == 0)
{
   output = "There's nothing in the dictionary."
}
else if(dict.Count ==1)
{
   string only_key;
   foreach (string key in dict.Keys)
   {
      //Surely there is a better way to do this
      only_key = key;
   }
   output = "Entry " + only_key + " has value " + dict[key] + ".";
}
else
{
   StringBuilder sb = new StringBuilder();
   sb.Append("The following entries are in the dictionary:");
   foreach (string key in dict.Keys)
   {
      sb.Append(Environment.NewLine + " * " + key + ": " + dict[key];
   }
   output = sb.ToString();
}
Dictionary dict=new Dictionary();
//填充字典的代码
字符串输出;
如果(dict.Count==0)
{
output=“字典里什么都没有。”
}
else if(dict.Count==1)
{
仅字符串_键;
foreach(dict.Keys中的字符串键)
{
//当然有更好的方法来做到这一点
仅_键=键;
}
output=“Entry”+仅_键+”具有值“+dict[key]+”;
}
其他的
{
StringBuilder sb=新的StringBuilder();
附加(以下词条在字典里:);
foreach(dict.Keys中的字符串键)
{
sb.Append(Environment.NewLine+“*”+key+”:“+dict[key];
}
输出=sb.ToString();
}
当我知道字典只有一个键时,我不喜欢在字典上做foreach循环来获取该键,但我不确定是否有更好的方法


有什么更好的方法可以做到这一点?

在遍历字典时,不需要为字典编制索引。在遍历字典时,您可以像这样访问键和值:

Dictionary<string, string> dict = new Dictionary<string, string>();
foreach (var thisItem in dict)
{
    output = $"Entry {thisItem.Key} has value {thisItem.Value}.";
}
Dictionary dict=new Dictionary();
foreach(dict中的var此项)
{
输出=$“条目{thisItem.Key}的值为{thisItem.value}。”;
}
您可以使用LINQ:

string only_key=dict.Keys.Single();

Single
(除了消除了
foreach
)的一个优点是,如果在调用
dict.Count==1
string only_key=dict.Keys.Single();

之间向字典添加了一个对象,那么它将抛出一个异常。您可以使用LINQ的扩展方法来获取第一个(并且仅限于此)键/值对:

else if (dict.Count == 1)
{
  var keyValuePair = dict.First();
  output = "Entry " + keyValuePair.Key + " has value " + keyValuePair.Value + ".";
}
说到LINQ,您还可以使用它替换
else
块:

else
{
  var header = "The following entries are in the dictionary:" + Environment.NewLine;
  var kvPairs = dict.Select(p => " * " + p.Key + ": " + p.Value);
  output = header + string.Join(Environment.NewLine, kvPairs);
}

你是对的-如果字典只有一个项,你不需要循环遍历字典键

如果您知道只有一项,则可以执行以下操作:

dict.Values.First()

不同之处在于
Single
如果没有一个条目,则会引发异常。另一个答案建议使用此选项,以防在检查计数==1后立即将某些内容添加到字典中。我不同意。如果这是多线程的内容,而另一个进程可能正在修改字典,则下一部分由于同样的原因,在字典中迭代键也会有风险。但是,除非你知道你正在做一些多线程的事情,否则你不必担心这一点。(如果是这样,你可以使用
ConcurrentDictionary

处理集合时要遵循的一个好模式是以相同的方式处理任意数量的项(1个或多个)。如果要从字典创建项列表,但只有一个项,则创建一个项列表。类似于

您的词典有(1)项:
关键字:abc值:xyz


然后,如果没有项目,您可以选择以不同的方式处理它。

var-key=
dict.Keys[0]
var-kvp=dict.Single();output=“Entry”+kvp.key+“具有值”+kvp.value+”
如果有人在执行此操作时向字典添加键,则遍历键的第二部分将爆炸。@ScottHannen-你所说的“第二部分”是什么意思?OPs示例中的哪个代码会爆炸?
foreach(dict.keys中的字符串键)
。如果另一个线程中的某个线程正在修改字典,那么这可能会有问题。在迭代过程中可以添加或删除项。如果我们关心多线程,那么它应该是一个
ConcurrentDictionary
。是的-会有问题,因为您将打印找到的最后一个键,而不是所有键。我不认为它会爆炸(即抛出异常)?但不管怎样,结果都不会像预期的那样。您必须在所有已发布的代码行周围使用一个锁(以及无论何时使用字典)为了确保在整个if/else if/else-ConcurrentDictionary中查看相同的词典,只需在多个线程上修改词典即可。
dict.Values.Single()