修改字典值是可能的。什么是正确的方法?

我有填充的字典,我无法控制。

我需要修改值我该怎么做?

我把一个简单的例子放在一起来解释这个问题

class Program { static void Main(string[] args) { Dictionary CustomerOrderDictionary = new Dictionary(); CustomerOrderDictionary.Add(new Customer { Id = 1, FullName = "Jo Bloogs" },3); CustomerOrderDictionary.Add(new Customer { Id = 2, FullName = "Rob Smith" },5); //now I decide to increase the quantity but cannot do the below as value has no setter foreach (var pair in CustomerOrderDictionary) { if(pair.Key.Id==1) { pair.Value = 4;///ERROR HERE } } } } public class Customer { public int Id { get; set; } public string FullName { get; set; } } 

有什么建议? 非常感谢

我建议您先确定哪些密钥需要修改,然后迭代这些修改。 否则,当你迭代它时,你最终会修改一个集合,这将引发exception。 例如:

 // The ToList() call here is important, so that we evaluate all of the query // *before* we start modifying the dictionary var keysToModify = CustomerOrderDictionary.Keys .Where(k => k.Id == 1) .ToList(); foreach (var key in keysToModify) { CustomerOrderDictionary[key] = 4; } 

这里的问题是对键入KeyValuePair ,它是一个只读对象,不能修改。 此外, KeyValuePair集合是一种查看字典内容(不更改字典)的方法。

你想在这里做的只是直接修改字典。 KeyValuePairKey可用于更新字典中的相同条目。

 if(pair.Key.Id==1) { CustomerOrderDictionary[pair.Key] = 4; } 

编辑

正如Jon指出的那样,赋值将使迭代器无效。 最简单但无效的路线是在循环开始时复制枚举器。

 foreach (var pair in CustomerOrderDictionary.ToList()) 

这是另一种方法

1)创建一个新类

  // wrapper class to allow me to edit a dictionary public class IntWrapper { public int OrderCount{ get; set; } } 

2)更改此声明

  Dictionary CustomerOrderDictionary = new Dictionary(); 

3)分配你的变量

  pair.Value.OrderCount = 4; 
 foreach (Customer customer in customers.Keys) { if ( customer.Id == 1 ) customers[ customer ] = 4; } 
 CustomerOrderDictionary[1] = 4; 

这是一种方法(仅指定值部分..):

 CustomerOrderDictionary[new Customer { Id = 1, FullName = "Jo Bloogs" }]=4 

请注意,“1”不是您词典中的键。 Customer是,所以你必须使用它。

另请注意, Customer应按照此处的说明实现IEquatable

好的,在您的示例中,您实际上只是找到Id = 1的Customer对象的条目并更新关联的值。 实际上,我认为在更新字典中的关联值之前,您的代码可能能够获得对您的目标Customer对象的引用。 如果是这种情况,则不需要循环。

下面是一个非常简单的示例,其中不需要循环,因为您的代码已经引用了customer1变量。 虽然我的示例过于简化,但概念是您可能通过迭代字典之外的其他方式获得对所需Customer对象的引用。

  static void Main(string[] args) { Dictionary CustomerOrderDictionary = new Dictionary(); Customer customer1 = new Customer { Id = 1, FullName = "Jo Bloogs" }; Customer customer2 = new Customer { Id = 2, FullName = "Rob Smith" }; CustomerOrderDictionary.Add(customer1, 3); CustomerOrderDictionary.Add(customer2, 5); // you already have a reference to customer1, so just use the accessor on the dictionary to update the value CustomerOrderDictionary[customer1]++; } 

如果需要根据其他一些条件对多个Customer对象执行某种更新,则可能需要循环。 以下示例假定您将拥有除存储Customer对象的字典之外的某些集合,并且您可以使用该Customer对象集合来标识需要更新字典中的关联值的那些集合。

  static void Main(string[] args) { // presumably you will have a separate collection of all your Customer objects somewhere List customers = new List(); Customer customer1 = new Customer { Id = 1, FullName = "Jo Bloogs" }; Customer customer2 = new Customer { Id = 2, FullName = "Rob Smith" }; Customer customer3 = new Customer { Id = 3, FullName = "Rob Zombie" }; customers.Add(customer1); customers.Add(customer2); customers.Add(customer3); Dictionary CustomerOrderDictionary = new Dictionary(); CustomerOrderDictionary.Add(customer1, 3); CustomerOrderDictionary.Add(customer2, 5); // let's just say that we're going to update the value for any customers whose name starts with "Rob" // use the separate list of Customer objects for the iteration, // because you would not be allowed to modify the dictionary if you iterate over the dictionary directly foreach (var customer in customers.Where(c => c.FullName.StartsWith("Rob"))) { // the dictionary may or may not contain an entry for every Customer in the list, so use TryGetValue int value; if (CustomerOrderDictionary.TryGetValue(customer, out value)) // if an entry is found for this customer, then increment the value of that entry by 1 CustomerOrderDictionary[customer] = value + 1; else // if there is no entry in the dictionary for this Customer, let's add one just for the heck of it CustomerOrderDictionary.Add(customer, 1); } } 

如果不是这种情况,并且您可用的Customer对象的唯一来源是字典本身,那么在迭代之前,您需要将这些对象的某种克隆/复制到单独的列表/数组中。修改字典。 请参阅Jon Skeet对此案的回答; 他建议在字典的Keys属性上使用Wherefilter,并使用ToList方法创建一个单独的List实例以进行迭代。