【问题标题】:Iterating over KeyValuePair (as a key in dictionary) is not working迭代 KeyValuePair(作为字典中的键)不起作用
【发布时间】:2017-09-18 13:29:50
【问题描述】:

以下是我的功能:-

public void deleteAllCarsWithType(Dictionary < KeyValuePair<string, string> , car > dictCar, string typeOfCar)
{
  var keyValuePairs = dictCar.Where(keyValuePair => keyValuePair.Key.Equals(typeOfCar));

  //var count = keyValuePairs.Count();
  //this also gives the size of keyValuePairs as 0.

  foreach (var keyValuePair in keyValuePairs)
  {
    dictCar.Remove(keyValuePair.Key);
  }
} 

KeyValuePair&lt;string, string&gt; 是字典的键,carType 是键,carModel 是汽车的型号。

当我运行它的单元测试时

[TestMethod]
public void DeleteSameCarTypeTest()
{
  Dictionary<KeyValuePair<string, string>, car> Dictionary = new Dictionary<KeyValuePair<string, string>, car>();
  Dictionary.Add(new KeyValuePair<string, string>("x", "y"), new car());
  Dictionary.Add(new KeyValuePair<string, string>("x", "z"), new car());

  new Program().deleteAllCarsWithType(Dictionary, "x");
  Assert.AreEqual(0, Dictionary.Count);
}

显示预期 0 和实际 2 失败。

当我调试它时,我发现 keyValuePairs 具有预期的两个值(与 carType "x" 一起)但是当我进入 foreach 循环时它不会进入并说 @987654330 的计数@ 是 0。然后我试图得到keyValuePairsCount,它也即将到来0。我不知道我做错了什么。请帮帮我。

【问题讨论】:

  • @BradleyUffner 我正在迭代 keyValuePair 而不是实际的字典。但首先它不会进入循环内部。你可以检查运行这个程序。
  • 这有点令人困惑...您知道在遍历字典 (dictCar.Where...) 时您会遍历 KeyValuePair&lt;KeyValuePair&lt;string, string&gt;, car&gt;... 而不是通过您的 KeyValuePair&lt;string, string&gt; 类型的键?跨度>
  • @RenéVogt 是的,你是对的。但正如我的测试表明的那样,它应该有两个值。
  • 所以keyValuePair.Key 的类型是KeyValuePair&lt;string, string&gt;,所以我猜它永远不会是EqualtypeOfCar...顺便说一句:永远只有一个键相等。
  • 我很确定将KeyValuePair&lt;TKey,TValue&gt; 作为字典的键是个坏主意。我不认为这符合您的期望,因为KeyValuePairEquals(和GetHashCode)方法无法按字典键的要求工作。

标签: c# unit-testing dictionary ienumerable


【解决方案1】:

keyValuePair.Key 是一个 KeyValuePair。 你需要:

var keyValuePairs = dictCar.Where(keyValuePair => keyValuePair.Key.Key.Equals(typeOfCar));

事实上,正如其他人所指出的,还需要进行一些更改:

private static void deleteAllCarsWithType(Dictionary<KeyValuePair<string, string>, car> dictCar, string typeOfCar)
{
    var keyValuePairs = dictCar.Where(keyValuePair => keyValuePair.Key.Key.Equals(typeOfCar)).ToArray();

    foreach (var keyValuePair in keyValuePairs)
    {
        dictCar.Remove(keyValuePair.Key);
    }               
}

【讨论】:

  • 正如Juan指出的那样,否则你会在迭代过程中删除一个项目,这将导致在foreach中抛出异常。
  • 所以keyValuePairs 实际上是对字典的实际key 的引用,因此通过循环从字典中删除。我说的对吗?
  • linq 使用惰性求值,这意味着如果更改原始集合,则更改从 linq 返回的集合。要缓存集合(保持固定),您需要使用 ToArray 或 ToList。
【解决方案2】:

您正在查看与键相对的值。

将您的代码更改为:

private static void deleteAllCarsWithType(Dictionary<KeyValuePair<string, string>, car> dictCar, string typeOfCar)
{
    var keyValuePairs = dictCar.Keys.Where(keyValuePair => keyValuePair.Key.Equals(typeOfCar)).ToArray();

    foreach (var keyValuePair in keyValuePairs)
    {
        dictCar.Remove(keyValuePair);
    }               
}

请注意,我还将查询转换为数组。否则循环会因为你修改了集合而失败。

【讨论】:

    猜你喜欢
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    相关资源
    最近更新 更多