12

好的,所以 List<> 包含为您提供 ReadOnlyCollection 的 AsReadOnly()。我需要的是有一个 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) 来限制添加到此列表,同时不允许使用 list.Add(一些项目)。问题是我使用NHibernate需要IList 接口,所以我不能在 IList 上转换/调用 AsReadOnly() (它不包含此方法)。

你会推荐什么方法来解决这种情况?我只需要一种方法让 NHibernate 以某种方式设置所需的集合,但我还需要限制用户。

4

5 回答 5

30

你可以模仿AsReadOnly()

public ReadOnlyCollection<Abc> List
{
    get { return new ReadOnlyCollection<Abc>(list); }
}

更新
这不会创建list. ReadOnlyCollection不复制数据,它直接在提供的列表上工作。请参阅文档

只读集合只是一个带有防止修改集合的包装器的集合;因此,如果对基础集合进行了更改,则只读集合会反映这些更改。
此构造函数是 O(1) 操作。

于 2011-08-29T08:10:23.380 回答
7

尝试

return new ReadOnlyCollection<Abc> (list);
于 2011-08-29T08:09:29.180 回答
1

使用以下方式,

public class Test
    {

        private IList<SubTest>      _subTests;


        public virtual void AddSubTest(SubTest SubTest)
        {
            if (_subTests == null)
                _subTests = new List<SubTest>();

            _subTests.Add(SubTest);

            return this;
        }


        public virtual IReadOnlyList<SubTest> SubTests
        {
            get
            {
                if (_subTests == null)
                    _subTests = new List<SubTest>();

                return _subTests.AsReadOnly();
            }
        }




        public void RemoveSubTest( SubTest SubTest )
        {
            if( _subTests == null ) 
                return;

            _subTests.Remove( SubTest );            
        }

    }

使用以下映射,它会将值设置为字段而不是只读列表的属性

<bag 
      name="SubTests" table="SubTest" lazy="true" access="field.camelcase-underscore"
      optimistic-lock="false"
      >
      <key column ="TestID" />
      <many-to-many class="SubTest, Domain" column="SubTestID" />
    </bag>
于 2011-08-29T08:14:36.917 回答
1

您还可以返回IEnumerable<Abc>只读迭代器并提供添加和删除元素的方法。

于 2011-08-29T11:57:41.597 回答
1

IEnumerable<Abc>在我看来,最好的方法是使用Jon Skeet 建议的方法返回:

public IEnumerable<Abc> Abcs {
    get { return list.Skip(0); }
}

如果您不担心消费者背弃您IEnumerable<T>IList<T>您可以直接退货IEnumerable<T>

ReadOnlyCollection<T>有一些严重的缺陷,主要是它实现了,IList<T>所以它确实有 Add 和 Remove 方法。如果消费者忽略检查其 ReadOnly 属性,这可能会导致运行时错误。我强烈建议不要使用它。

于 2011-08-29T12:43:37.197 回答