c# - 无法修改“System.Collections.Concurrent.ConcurrentDictionary”的返回值

标签 c# .net concurrency

我在尝试修改 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。如果您打算修改有关它的某些内容(即您正在创建的内容并不代表谨慎的“值(value)”,并且更改某些内容并不会使它本质上成为其他内容),那么您绝对使用。在解决问题方面,只需将 struct 替换为 class 即可。

但是,我还建议公开属性而不是字段。 .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;
    }
} 

我有一种感觉,您的类(class)可以使用更有意义的名称(除非“Triple”在您的工作中具有一些我不知道的特定行业含义),但希望这足以有所帮助.

关于c# - 无法修改“System.Collections.Concurrent.ConcurrentDictionary”的返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27159683/

相关文章:

c# - System.DirectoryServices.DirectorySearcher.PropertiesToLoad 中有哪些不同的可用属性

c# - 使用C#读取Excel文件

c# - 标记扩展、构造函数和智能感知

java - 将项目插入队列后,BlockingDeque 不会解除阻塞

python - Odoo _check_concurrency 从未触发过?

c# - 如何同时压缩两个 IAsyncEnumerable?

c# - 在 ABC pdf 中渲染 pdf 之前让 Javascript 完成

c# - 我的扩展方法可以变得更好吗? BlockBlobClient GetBlockById dotnet

c# - Application.Exit需要调用两次

c# - 在 C# 中,为什么从 List 创建 HashSet 比从 HashSet 开始更快?