【问题标题】:Cannot add an item to the Collection property. Please hеlр me, please无法将项目添加到 Collection 属性。请帮帮我,拜托
【发布时间】:2019-04-23 15:47:26
【问题描述】:

我正在尝试将一个项目添加到 SynchronizedCollection,但只有当我将它直接添加到字段中时它才有效。

        _s = new SynchronizedCollection<int>();
        _s.Add(01010);
        S.Add(123);

    private SynchronizedCollection<int>  _s;
    public SynchronizedCollection<int> S
    {
        get
        {

            lock (_s.SyncRoot)
            {
                return new SynchronizedCollection<int>(_s.SyncRoot, _s);
            }
        }

        private set
        {
            _s= value;
        }
    }

如何让它发挥作用?

【问题讨论】:

  • 您的get 每次返回集合的新实例时,您应该返回_s...所以您正在向新集合添加元素,然后您实际上将其丢弃...:)
  • 您的set 是私有的,因此您没有提供在课堂外添加项目的权限。
  • 您可以考虑改用System.Collections.Concurrent 集合之一,可能是ConcurrentBag&lt;T&gt; 类。
  • 您能否举例说明您是如何尝试添加项目的,以及您如何验证它没有被添加?

标签: c# list asynchronous concurrency synchronization


【解决方案1】:

只有当我将它直接添加到字段中时它才有效

因为您没有将新创建的SynchronizedCollection 分配给_s。每次调用S getter 时都会创建新集合,所有元素都是copied,并将元素添加到其中。 _s 实际上保持不变。

lock (_s.SyncRoot)
{
    _s = new SynchronizedCollection<int>(_s.SyncRoot, _s);
    return _s;
}

虽然我不认为每次都需要创建新的集合,SynchronizedCollection 本身是线程安全的,所以你可以直接返回 _s 但不知道实际情况为什么要这样做。

【讨论】:

  • 它实际上回答了。问题是为什么没有使用 getter 将项目添加到集合中,而只是使用字段。
  • 啊,我明白你的意思了。稍作修改,这样我就可以删除反对票了~!
【解决方案2】:

一种选择是公开一个公共 AddItem 方法,该方法采用 int 并将其添加到您的私有字段:

public void AddItem(int item)
{
    _s.Add(item);
}

显然,您也可以在 get 方法中返回私有字段 _s 而不是它的副本,然后客户可以通过该引用直接在私有字段上调用 ​​Add,但是没有多大意义在它是私人的。 :)

【讨论】:

    猜你喜欢
    • 2023-02-02
    • 1970-01-01
    • 2022-06-11
    • 2017-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多