好的,所以 List<>包含 AsReadOnly(),它为您提供 ReadOnlyCollection。我需要的是有一个 IList 类型的字段,以及一个将为该列表返回 ReadOnlyCollection 的属性。
示例类:
class Test
{
private IList<Abc> list;
public AddToList(Abc someItem) { /* adds inside the list */... }
public ReadOnlyCollection<Abc> List { get { return ??? } } // <- no "set" here!
}
场景如下:当将项目添加到列表中时,我需要在类中具有一些自定义逻辑,并且我想通过调用 AddToList(someitem) 来限制添加到此列表,同时不允许使用列表.添加(某些项目)。问题是我使用 NHibernate ,它需要 IList 接口,所以我无法在 IList 上强制转换/调用 AsReadOnly() (它不包含此方法)。
您建议采取什么方法来解决这种情况?我只需要一种方法让 NHibernate 以某种方式设置所需的集合,但我还需要限制用户。
OK, so List<> contains the AsReadOnly() which gives you the ReadOnlyCollection. What I need is to have a field of IList type, and a property which would return a ReadOnlyCollection for this list.
Example class:
class Test
{
private IList<Abc> list;
public AddToList(Abc someItem) { /* adds inside the list */... }
public ReadOnlyCollection<Abc> List { get { return ??? } } // <- no "set" here!
}
The scenario is following: I need to have some custom logic inside my class when the item is added into the list, and I want to restrict adding to this list by calling AddToList(someitem), while not allowing the usage of list.Add(someItem). The problem is that I use NHibernate which requires the IList interface, so I cannot cast / call the AsReadOnly() on the IList (it does not contain this method).
What way would you recommend to solve this situation? I simply need a way for NHibernate to set the needed collection in some way, but I also need to restrict users.
发布评论
评论(6)
您可以模拟
AsReadOnly()
:UPDATE:
这不会创建
list
的副本。ReadOnlyCollection
不复制数据,它直接在提供的列表上工作。请参阅文档:You can just emulate
AsReadOnly()
:UPDATE:
This doesn't create a copy of
list
.ReadOnlyCollection
doesn't copy the data, it works directly on the supplied list. See documentation:尝试
try
使用以下方式,
使用以下映射,它将值设置为字段而不是只读列表的属性
Use following way,
use following mapping, and it would sets the value to the field not to the property which is read only list
您还可以返回 IEnumerable,它是只读迭代器,并提供添加和删除元素的方法。
You can also return
IEnumerable<Abc>
which is read only iterator and provide methods for adding and removing elements.在我看来,最好的方法是使用 Jon Skeet 建议的方法:
如果您不担心消费者将
IEnumerable
投射回IList
您可以只返回IEnumerable
。ReadOnlyCollection
有一些严重的缺陷,主要的缺陷是它实现了IList
,因此它确实具有 Add 和 Remove 方法。如果消费者忽略检查其 ReadOnly 属性,这可能会导致运行时错误。我强烈建议不要使用它。In my opinion the best way to do this is to return
IEnumerable<Abc>
using the method suggested by Jon Skeet:If you're not worried about consumers casting the
IEnumerable<T>
back toIList<T>
you can just returnIEnumerable<T>
.ReadOnlyCollection<T>
has some serious flaws, the primary one being that it implementsIList<T>
so it does have Add and Remove methods. This can lead to runtime errors if consumers neglect to check its ReadOnly property. I strongly recommend against using it.从 .NET 7 开始,
IList
接口现在提供了一个可供您使用的扩展方法:IList.AsReadOnly()
https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.asreadonly?view=net-8.0
As of .NET 7, there's now an extension method available on the
IList
interface that you can use:IList.AsReadOnly()
https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.asreadonly?view=net-8.0