无法修改“System.Collections.Concurrent.ConcurrentDictionary”的返回值
本文关键字:ConcurrentDictionary 返回值 Concurrent Collections 修改 System | 更新日期: 2023-09-27 18:32:04
我在尝试修改ConcurrentDictionary
中的项目时遇到非常奇怪的错误:
private ConcurrentDictionary<string, Tripple> SeenEnoughDict =
new ConcurrentDictionary<string, Tripple>();
private struct Tripple
{
public int prev_antenna;
public int num_of_times_seen;
public Timer timer;
// ctor
public Tripple(int antenna, Timer tm)
{
this.prev_antenna = antenna;
this.num_of_times_seen = 1;
this.timer = tm;
}
}
// several items were added to the dictionary
Parallel.ForEach(_myReaderTC.Cast<Tag>(), t => {
// attempting to modify the item
// t.ID is string
SeenEnoughDict[t.ID].num_of_times_seen = SeenEnoughDict[t.ID].num_of_times_seen + 1;
}
最后一行抛出错误:
Error 149 Cannot modify the return value of
'System.Collections.Concurrent.ConcurrentDictionary<string,Tripple>.this[string]'
because it is not a variable
这个错误的有趣之处在于,http://pastebin.com/0cQJMcUD 可以正常工作。最近,我将我的解决方案从 2010 年转换为 2013 年。在 2010 年,我使用了从 .NET 4 向后移植到 3.5 的并发集合(我从 NuGet 获得它)。
这是因为您的类型是struct
。一般来说,除非您知道您有特定的原因来创建值类型(struct
),否则您实际上应该创建一个class
。如果你要修改它的某些东西(即你正在创建的东西并不代表一个谨慎的"价值",改变某些东西并不会使它本质上成为其他东西),你绝对应该使用class
。在解决问题方面,只需用class
替换struct
就可以了。
但是,我也建议公开属性而不是字段。.NET 语言中的一般习惯用法是使用private
支持字段,并在必要时使用属性在声明类外部公开它们。所以取而代之的是:
public class Foo
{
public int MyValue;
}
你会这样做:
public class Foo
{
private int myValue;
public int MyValue
{
get { return myValue; }
set { myValue = value; }
}
}
我意识到这有点罗嗦,但对于简单的属性(简单的获取/设置操作,除了设置所需字段的值之外没有任何内容),您可以使用"自动属性"
public class Foo
{
public int MyValue { get; set; }
}
对于简单的获取/设置操作,属性语法不再冗长,但仍为您提供属性为您提供的灵活性和关注点分离。
最后,我建议采用PascalCase名称,因为这是大多数.NET语言中可以找到的名称。
完成所有这些更改后,您的类将如下所示:
private class Tripple
{
public int PrevAntenna { get; set; }
public int NumOfTimesSeen { get; set; }
public Timer Timer { get; set; }
// ctor
public Tripple(int antenna, Timer tm)
{
this.PrevAntenna = antenna;
this.NumOfTimesSeen = 1;
this.Timer = tm;
}
}
我有一种感觉,你的班级可以使用一个更有意义的名字(除非"Tripple"在你的工作中有一些我只是不知道的行业特定含义),但希望这足以有所帮助。