不能修改Dictionary的返回值,因为它不是一个变量
本文关键字:变量 一个 Dictionary 修改 返回值 因为 不能 | 更新日期: 2023-09-27 17:49:30
出现如下错误:无法修改System.Collections.Generic.Dictionary的返回值。This [string]'因为它不是一个变量。'
我代码:Dictionary<string, lim> urlsLimited = new Dictionary<string, lim>();
struct lim
{
public int min;
public int max;
}
void main ()
{
....
foreach (KeyValuePair<string, lim> pair in urlsLimited)
{
string like = od.LikeDiscussions(pair.Key);
if (like == "Like")
{
lock (locker)
{
urlsLimited[pair.Key].min++; // error
}
}
}
....
}
如何迭代urlsLimited[pair.Key].min++?
您需要将该值赋给一个局部变量,执行自增操作,然后将其设置回字典。
foreach (KeyValuePair<string, lim> pair in urlsLimited)
{
string like = od.LikeDiscussions(pair.Key);
if (like == "Like")
{
lock (locker)
{
lim val = pair.Value;
val.min++;
urlsLimited[pair.Key] = val;
}
}
}
请参阅Jon Skeet对相关问题的回答https://stackoverflow.com/a/6255368/1149773.
考虑如下:
struct lim {
public readonly int min;
public readonly int max;
public lim(int min = 0, int max = 0) {
this.min = min;
this.max = max;
}
}
// ... later in your loop body
var currentLim = urlsLimited[pair.Key];
urlsLimited[pair.Key] = new lim(currentLim.min + 1, currentLim.max);
不可变结构体,很明显你在做什么。:)
Dictionary
的索引器返回lim
的副本(因为它是值类型)。除非您将此副本分配给变量,否则您对min
所做的任何修改都将丢失。这就是你得到错误的原因。但在您的情况下,您不希望增加副本的min
字段。
解决方案正确识别您可以通过索引器将lim
的新实例设置到字典中。
要记住的是,此时你已经在字典中迭代了,所以再次在字典中搜索当前正在求值的项似乎非常低效。您必须这样做,因为当您迭代Dictionary
时,它还返回它通过KeyValuePair
保存的数据的副本,因为这也是一个值类型。lim
类型的Value
也被复制到KeyValuePair
中,因为它也是一个值类型。
我想说你最好把lim
从一个结构体变成一个类,因为这样KeyValuePair
的Value
属性将总是引用相同的实例(而不是副本),你写的代码将编译,并且变得更容易阅读。
但是,如果你真的需要在读取时获得结构体的性能增益,那么我会重新编写代码,以便在向字典添加值时增加min
字段