有这样的错误:无法修改'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 ++?
答案 0 :(得分:8)
您需要将值分配给局部变量,执行增量,然后将其设置回字典。
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。
答案 1 :(得分:3)
考虑这样的事情:
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);
不可变的结构和明显的你正在做的事情。 :)
答案 2 :(得分:0)
Dictionary
的索引器返回lim
的副本(因为它是一种值类型)。除非您将此副本分配给变量,否则您对min
所做的任何修改都将丢失。这就是为什么您得到错误。就您而言,尽管您不想增加副本的min
字段。
这些解决方案正确地表明您可以通过索引器为字典设置lim
的新实例。
要记住的一点是,您已经在字典上进行迭代,因此再次在字典中搜索当前正在评估的项目似乎效率很低。您必须执行此操作,因为在迭代Dictionary
时,它还会返回通过KeyValuePair
保存的数据的副本,因为这也是一个值类型。类型Value
的{{1}}也被复制到lim
中,因为它也是一个值类型。
我想说,您最好将KeyValuePair
从结构更改为类,因为lim
的{{1}}属性将始终引用同一实例(而不是复制),您编写的代码将被编译,并且变得更加易于阅读。
但是,如果您确实需要在读取时获得该结构的性能提升,那么我会重新编写您的代码,以便在将值添加到字典时,您可以增加Value
字段。