【问题标题】:C# 2 keys and a value [duplicate]C# 2个键和一个值[重复]
【发布时间】:2026-02-01 07:40:01
【问题描述】:

我想存储我的玩家分数。我会有不同的世界,世界有不同的层次。 这就是为什么我想要类似的东西..

public static void AddScore(int world, int level, int rolls, float time, float score)
{
   _scores[world][level] = new LevelScore(rolls, time, score);
}
public static LevelScore GetScore(int world, int level)
{
    if (_scores.ContainsKey(world))
    {
        var scoresOfWorld = _scores[world];

        if(scoresOfWorld.ContainsKey(level))
        {
            return scoresOfWorld[level];
        }
    }

    return new LevelScore();
}

我用字典里面的字典试过了..

public static Dictionary<int, Dictionary<int, LevelScore>> _scores = new Dictionary<int, Dictionary<int, LevelScore>>();

但是 AddScore(...) 导致“KeyNotFoundException:给定的键不在字典中”。 我认为如果密钥不存在,则会添加密钥。对我来说,轻松归档我想要的内容的最佳方式是什么?

【问题讨论】:

  • 使用元组作为单个字典的键可能更容易:Dictionary&lt;(int World, int Level), LevelScore&gt;
  • 这解决了我的问题!谢谢你:)

标签: c# visual-studio unity3d


【解决方案1】:

您可以使用具有键作为世界和关卡组合的字典。

var scores = new Dictionary<string, LevelScore>();
....
if (!scores.ContainsKey($"{world}_{level}"))
{
    scores.Add($"{world}_{level}", value);
}
else
{
    ....
}

【讨论】:

  • 使用字符串的问题是您必须解析键(例如在枚举期间)才能得到这两个部分。这就是为什么我在对这个问题的评论中建议一个元组。 (这只是一个评论,因为它没有回答 实际 问题,也没有这个问题。)
  • 是的,同意,使用元组更简单:) 谢谢!
【解决方案2】:

AddScore(...) 导致“KeyNotFoundException”

那是因为你需要在外部字典中添加一个新的内部Dictionary&lt;int, LevelScore&gt;,然后才能访问它

dict[0][1] = ...

如果在dict[0] 的外部字典中没有注册内部Dictionary&lt;int, LevelScore&gt;,那么在尝试检索内部字典并将其[1]'th 索引设置为... 时,您会得到一个KeyNotFound。

您需要一个嵌套字典集代码,如下所示:

if(!dict.TryGetValue(world, out var innerDict)) 
  dict[world] = innerDict = new Dictionary<int, LevelScore>();

innerDict[level] = new LevelScore(rolls, time, score);

if 要么检索内部字典(如果存在),要么确保创建一个(并分配给 innerDict 变量)(如果不存在)。这意味着第二行可以成功(因为 innerDict 是已知的并且已被检索,或者它是新的并且已设置)


如果您不继续使用该表单,则旧表单也可以使用(它只需要更多查找,但它们足够便宜,以至于以不被能够轻松阅读代码)):

//ensure key exists
if(!dict.ContainsKey(world)) 
  dict[world] = new Dictionary<int, LevelScore>();

dict[world][level] = new LevelScore(rolls, time, score);

【讨论】:

    【解决方案3】:

    您需要先为world 创建字典。它不是自动创建的。

    _scores[world] = new Dictionary<int, LevelScore>();
    _scores[world][level] = new LevelScore(rolls, time, score);
    

    【讨论】:

      【解决方案4】:

      最好的方法是使用关系数据集,而不是字典。 Dictionary 内的 Dictionary 是一个层次模型。看这段代码

      public class Score
          {
            
              public int World { get; set; }
              public int Level { get; set; }
              public int Rolls { get; set; }
              public float Time { get; set; }
              public float ScoreNum { get; set; }
          }
          public class ScoreBuilder
          { 
              public  List<Score> Scores { get; set; } = new List<Score>();
      
              public void AddScore(int world, int level, int rolls, float time, float score)
              {
                  var scoreObj = new Score { World = world, Level = level, Rolls = rolls, Time = time, ScoreNum = score };
                  Scores.Add(scoreObj);
              }
              public  Score GetScore(int world, int level)
              {
                  return Scores.FirstOrDefault(s=> s.World==world && s.Level==level);
              }
          }
      

      你可以很容易地添加新的分数,你可以很容易地获得任何分数,使用纯 Linq。

      如何使用

                 var scores = new ScoreBuilder();
      
                  scores.AddScore(....);
                  scores.GetScore(...)
      

      【讨论】:

        最近更新 更多