当前位置:  开发笔记 > 编程语言 > 正文

以只读方式返回集合

如何解决《以只读方式返回集合》经验,为你挑选了4个好方法。

我在多线程环境中有一个对象来维护一组信息,例如:

public IList Data 
{
    get 
    {
        return data;
    }
}

我目前return data;用a包裹ReaderWriterLockSlim来保护集合免于共享违规.但是,为了更加确定,我想将集合作为只读方式返回,这样调用代码就无法对集合进行更改,只能查看已经存在的集合.这是可能吗?



1> aku..:

如果基础数据存储为列表,则可以使用List(T).AsReadOnly方法.
如果可以枚举您的数据,则可以使用Enumerable.ToList方法将集合转换为List并在其上调用AsReadOnly.



2> nedruod..:

如果您的唯一目的是让调用代码不出错,并且只在读取所有必要的内容时修改集合就是返回一个不支持Add,Remove等的接口.为什么不返回IEnumerable?调用代码必须进行转换,如果不知道他们正在访问的属性的内部,他们不太可能做.

但是,如果您的意图是阻止调用代码观察来自其他线程的更新,则必须回退到已经提到的解决方案,以根据您的需要执行深度或浅层复制.



3> Bill K..:

我投票支持你接受的答案并同意 - 但是我可以给你一些考虑吗?

不要直接返回集合.创建一个准确命名的业务逻辑类,以反映集合的目的.

这样做的主要优点在于您无法将代码添加到集合中,因此每当您在对象模型中拥有本机"集合"时,您始终会在整个项目中传播非OO支持代码以访问它.

例如,如果您的收藏是发票,那么您的代码中可能有3个或4个位置,您可以在其中迭代未付的发票.你可以有一个getUnpaidInvoices方法.然而,当你开始考虑像"payUnpaidInvoices(payer,account);"这样的方法时,真正的力量就会出现.

当你传递集合而不是编写对象模型时,整个类的重构都不会发生在你身上.

另请注意,这会使您的问题特别好.如果您不希望人们更改集合,则您的容器不需要包含mutator.如果您稍后决定在一个案例中您实际上必须修改它,您可以创建一个安全机制来执行此操作.

当你在本地集合中传递时,你如何解决这个问题?

此外,无法使用额外数据增强本机集合.下次当您发现(Collection,Extra)传递给一个或两个以上的方法时,您会认识到这一点.它表示"Extra"属于包含您的集合的对象.



4> Daniel Fortu..:

我觉得你在这里混淆概念.

ReadOnlyCollection为现有集合提供了一个只读包装器,允许您(A类)传递对集合安全的引用,因为调用者(B类)无法修改集合(即无法添加删除任何元素集合.)

绝对没有线程安全保证.

如果你(A类)继续修改底层集合后再将其移出,ReadOnlyCollection那么B类将会看到这些更改,任何迭代器都会失效等等,并且通常会对集合的任何常见并发问题持开放态度.

此外,如果集合中的元素是可变的,则您(A类)调用者(B类)都将能够更改集合中对象的任何可变状态.

您的实施取决于您的需求: - 如果您不关心调用者(B类)看到对集合的任何进一步更改,那么您可以克隆该集合,将其移出并停止关怀. - 如果您确实需要调用者(B类)来查看对集合所做的更改,并且您希望这是对线程安全的,那么您手上就会遇到更多问题.一种可能性是实现自己的线程安全的ReadOnlyCollection变体以允许锁定访问,但如果你想支持IEnumerable,这将是非平凡和非高效的,它仍然不会保护你免受可变元素的影响.采集.

推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有