C# 无法修改字典的返回值,因为它不是变量

C# 无法修改字典的返回值,因为它不是变量,c#,C#,出现以下错误:无法修改“System.Collections.Generic.Dictionary.this[string]”的返回值,因为它不是变量` 我的代码: Dictionary<string, lim> urlsLimited = new Dictionary<string, lim>(); struct lim { public int min; public int max; } void main () { .... for

出现以下错误:无法修改“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

            }
        }
    }
    ....
}
Dictionary urlsLimited=newdictionary();
结构lim
{
公共int min;
公共整数最大值;
}
空干管()
{
....
foreach(urlsLimited中的KeyValuePair对)
{
字符串like=od.LikeDiscussions(pair.Key);
if(like==“like”)
{
锁(储物柜)
{
urlsLimited[pair.Key].min++;//错误
}
}
}
....
}

如何迭代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;
        }
    }
}
foreach(urlsLimited中的KeyValuePair对)
{
字符串like=od.LikeDiscussions(pair.Key);
if(like==“like”)
{
锁(储物柜)
{
lim val=配对值;
val.min++;
urlsLimited[pair.Key]=val;
}
}
}

要想得到一个好的解释,请参考Jon Skeet对一个相关问题的回答:。

考虑以下内容:

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);

不可变的结构和显而易见的操作。:)

字典的索引器返回
lim
副本(因为它是值类型)。除非将此副本分配给变量,否则对
min
所做的任何修改都将丢失。这就是为什么会出现错误。但在您的情况下,您不希望增加副本的
min
字段

这些解决方案正确地确定您可以通过索引器将
lim
的新实例设置到字典中

需要记住的是,此时您已经在迭代字典,因此再次搜索字典以查找当前正在评估的项目似乎效率很低。您必须这样做,因为当您迭代
字典时
也会通过
键值对
返回它所持有的数据的副本,因为这也是一种值类型。类型为
lim
值也会复制到
KeyValuePair
中,因为它也是一种值类型

我认为最好将
lim
从一个结构更改为一个类,因为
KeyValuePair
Value
属性将始终引用同一个实例(而不是副本),您编写的代码将被编译,并且变得更易于阅读


但是,如果您确实需要在读取时获得结构的性能增益,那么我会重新编写代码,以便在向字典添加值时,您可以增加
min
字段。

可变结构是有害的。这是您应该避免使用它们的原因之一(我通常会使用“不可变结构”,以使操作更明显:
var oldLim=pair.Value;urlsLimit[pair.Key]=new lim{min=oldLim+1,max=oldLim.max};