代码之家  ›  专栏  ›  技术社区  ›  zendar

是否存在阻止添加对象的.NET集合接口?

  •  24
  • zendar  · 技术社区  · 15 年前

    我有一个类,它维护另一个类的对象列表。对象列表是公共属性。我要防止用户直接添加和删除对象以列出如下内容:

          MyObject.MyListProperty.Add(object);
    

    相反,我希望他们使用方法,在内部进行一些处理,然后将对象添加到列表中。

    我有一些想法:

    • 创建的后代 List<T> 覆盖添加和删除
    • 通过属性getter返回列表的新副本(列表相对较短,不超过30个对象)

    是否存在没有添加和删除的集合接口?

    编辑:
    我要和你一起去 ReadOnlyCollection<T> . 原因是可以更新包装的集合,并且更改将在只读对象中立即可见(请参阅 ReadOnlyCollection<T> AsReadOnly() )这允许只读列表只创建一次。

    问题在于 IEnumerable 是不是那个东西可以被还原成原来的 列表<t> 然后 直接操纵。

    7 回复  |  直到 14 年前
        1
  •  36
  •   Oded    14 年前

    你可以用 ReadOnlyCollection -把你的收藏包在这个里面,然后把 ReadOnlyCollection 致您所在班级的用户:

    return new ReadOnlyCollection(innerCollection);
    

    或者使用 AsReadOnly 方法 List<T> 班级:

    return innerCollection.AsReadOnly();
    

    这个 IEnumerable 接口将满足您的需要,因为它只有一个成员 GetEnumerator() ,这只允许您在项上迭代。

        2
  •  5
  •   James    15 年前

    最简单的选择是将列表公开为 IEnumerable , ICollection ReadOnlyCollection 通过公共财产。

    所以你可以自己创造 type 显示您的 Items 作为上述方法之一,但有一个内部添加方法,例如

    public class MyList<MyType>
    {
        private List<MyType> items;
    
        public MyList()
        {
            items = new List<MyType>();
        }
    
        public IEnumerable Items { get { return items.AsEnumerable(); } }
        public Add(MyType item)
        {
            // do internal processing
            items.Add(item);
        }
    }
    
        3
  •  5
  •   Peter Mortensen icecrime    15 年前

    也许吧 AsReadOnly 方法将完成此操作,将只读实例传递给public。

    否则, IEnumerable<T> 没有 Add 也不 Remove ,因此您可以执行以下操作:

    private List<int> _myList;
    public IEnumerable<int> MyList
    {
       get
       {
          return this._myList.ToList();
       }
    }
    

    我宁愿去 IEnumerable<t> (+份)至于 ReadOnlyCollection<T> ,因为:对基本列表(创建只读集合的依据)的更改将立即显示在只读集合的实例中。这可能会导致锁定和排列问题:)

        4
  •  2
  •   Florian Doyon    15 年前

    开箱即用 IEnumerable<T> 会在不暴露任何 Add Remove 可能诱使客户端获取运行时异常的公共方法。

    如果希望公共api明确声明集合是只读的,并且需要索引器,则必须在现有的 List<T> T[]

        5
  •  0
  •   Joe    15 年前

    你可以给他们一个对象,这个对象总是返回一个枚举器,他们可以用它来访问这个结构?

        6
  •  0
  •   AaronLS    15 年前

    不会真正回答您的问题,但如果您决定实施以下两个想法中的一个,则是有用的信息: 可以使用ToArray创建副本并返回数组。

    或者你可以这样做: http://en.csharp-online.net/CSharp_Generics_Recipes%E2%80%94Making_Read-Only_Collections_the_Generic_Way

        7
  •  0
  •   adrianm    15 年前

    ICollection(非泛型版本)仅获得IEnumerable+Count