【问题标题】:Alter/modify data from an existing keyValuePair更改/修改现有 keyValuePair 中的数据
【发布时间】:2016-04-27 06:06:41
【问题描述】:

我有这个

foreach (KeyValuePair<string, Object> tempData in tempList.ToDictionary(x => x.Key, y => y.Value))
{        
    tempData["fahrzeugA"] = "s";
}

但是使用tempData["fahrzeugA"] = "s"; 将不起作用。

我明白了:

无法将 [] 索引应用于类型表达式 'System.Collections.Generic.KeyValuePair'

如果我有一个想要更改的现有密钥 fahrzeugA,正确的语法是什么?

【问题讨论】:

  • ToDictionary 返回一个新对象。您不能以这种方式修改 tempList。
  • tempList中存储的类型是什么?键值对?
  • 你想做什么?更改tempList 中具有“fahrzeugA”键的项目?
  • 可能duplicate

标签: c# linq generics


【解决方案1】:

你可以应用这个:

 var tempList = new List<Test>();
 var dic = tempList.ToDictionary(x => x.Key, y => y.Value);
 foreach (var tempData in dic)
 {
      dic[tempData.Key] = "s";
 }

【讨论】:

  • 我不确定这是 OP 想要做的。也许他想更改tempList 中的项目而不是包含这些元素副本的独立字典。
  • 有什么用?为什么不在值选择器中选择"s"
  • 也许他改变了任何字典的某些值。
  • 如果没有foreachvar dic = tempList.ToDictionary(x =&gt; x.Key, y =&gt; "s");
  • 是的,我明白了。这是一种最简洁的方式。
【解决方案2】:

您不能更改键值对,因为它是一个不可变结构。改变它的唯一方法是创建一个新实例。该实例将独立于字典而存在。

如果要更改字典中的值,请使用字典上的 indexer 属性来更改值。

即使那样,字典也会立即超出范围,因此设置它没有用。它不会影响原始列表。

【讨论】:

    【解决方案3】:
    1. 检查KeyValuePair.Value Property。它是只读的,不能更改。
    2. ToDictionary 创建一个新对象。您不能通过访问其元素的值来更改原始对象。
    3. 您必须从原始列表中删除此特定项目并添加相同键的新项目。

      var removeIndex = tempList.FindIndex(kp => kp.Key == "fahrzeugA");
      tempList.RemoveAt(removeIndex);
      tempList.Add(new KeyValuePair<string, string>("fahrzeugA", "s"));
      

      如果有多个“fahrzeugA”项(在列表中有效但在字典中无效),请改用RemoveAll

    【讨论】:

      【解决方案4】:

      如果您的tempListList&lt;KeyValuePair&lt;string, Object&gt;&gt;,请输入:

      for (var i = 0; i < tempList.Count; ++i) {
          if (tempList[i].Key == "fahrzeugA") {
              tempList[i] = new KeyValuePair<string, object> ("fahrzeugA", "s"); // KeyValuePair<string, object> might be changed with your own type if you use something else.
              break; // If you want to modify only first KeyValuePair.
          }
      }
      

      【讨论】:

      • 当且仅当tempList 包含KeyValuePair 类型的项目时,这可能有效。但这是第一个改变tempList的答案。
      • @Vera rind True。如果它是带有KeyValue 元素的其他类型,那么new KeyValuePair&lt;string, object&gt; 需要使用其他类型初始化进行更改。
      【解决方案5】:

      如果您已成功将您的tempList 转换为字典,则只能有一个“fahrzeugA”(因为所有键都必须是唯一的),因此循环没有意义。

      你应该可以说:

      var dictionary = tempList.ToDictionary(x => x.Key, y => y.Value);
      dictionary["fahrzeugA"] = "s";
      

      如果你不想一开始就创建字典,你可以这样做:

      var matchingKeyValuePair = tempList.SingleOrDefault(x => x.Key == "fahrzeugA");
      if (matchingKeyValuePair != null) matchingKeyValuePair.Value = "s";
      

      如果您使用的是 .NET KeyValuePair&lt;TKey, TValue&gt; 列表,这是一个不可变结构,您可以将值替换为新的 KeyValuePair,如下所示:

      var matchingIndex = tempList.FindIndex(x => x.Key == "fahrzeugA");
      if (matchingIndex >= 0)
          tempList[matchingIndex] = new KeyValuePair<string, string>("fahrzeugA", "s");
      

      注意,这假设您只有一个键为“fahrzeugA”的项目。

      【讨论】:

      • 我不确定这是 OP 想要做的吗?我认为他试图更改 tempList 中的值 - 不是完全独立的字典。
      • 你真的可以修改KeyValuePair (stackoverflow.com/questions/13454721/…)吗?
      • 更好 - 但如果 tempList 中的项目是 KeyValuePair 类型,它们是不可变的并且是值类型。在这种情况下,检查 null 和更改值将不起作用。但我在原始问题中添加了一条评论,询问此列表中项目的类型。
      • 几乎完美。我假设tempList 的类型是List&lt;&gt;。它包含一个方法 FindIndex 方法,它接受一个谓词。使用它可以删除SingleOrDefault,检查返回的索引是否>= 0,并使用不带RemoveAtInsert 的列表索引器替换值。这可能会快一点,因为它不会在列表上多次迭代,也不会重新排列项目。
      • 无论如何,OP 似乎不会提供他想要实现的目标,所以我们只是在这里猜测。
      猜你喜欢
      • 2012-11-07
      • 2020-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-08
      相关资源
      最近更新 更多