是否有一个.NET集合接口阻止添加对象?

时间:2010-02-01 11:20:13

标签: c# .net collections list

我有一个维护另一个类的对象列表的类。对象列表是公共属性。我想阻止用户直接添加和删除对象到这样的列表:

      MyObject.MyListProperty.Add(object);

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

我有一些想法:

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

是否有一些没有添加和删除的集合界面?

修改
我要去ReadOnlyCollection<T>。原因是可以更新包装集合,并且只读对象中的更改将立即可见(请参阅ReadOnlyCollection<T>AsReadOnly()的MSDN代码示例)。这允许只读一次创建只读列表。

IEnumerable的问题是该对象可以转换回原始List<T>然后 直接操纵。

7 个答案:

答案 0 :(得分:36)

您可以使用ReadOnlyCollection - 将您的收藏打包并将ReadOnlyCollection返回给您的班级用户:

return new ReadOnlyCollection(innerCollection);

或使用AsReadOnly类的List<T>方法:

return innerCollection.AsReadOnly();

IEnumerable界面将满足您的需求,因为它只有一个成员GetEnumerator(),只允许您遍历项目。

答案 1 :(得分:5)

也许AsReadOnly方法可以解决这个问题,将只读实例交给公众。

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

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

我宁愿选择IEnumerable<T>(+副本)和ReadOnlyCollection<T>,因为:更改基本列表(从中创建只读集合)将立即显示在您的只读集合的​​实例。这可能会导致锁定和拖延问题:)

答案 2 :(得分:5)

您最简单的选择是通过公共财产将您的列表公开为以下IEnumerableICollection 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 :(得分:2)

开箱即用,只有IEnumerable<T>才能提供此功能,而不会泄露任何可能欺骗客户端获取运行时异常的AddRemove公共方法。

如果您希望公共API明确声明该集合是只读的并且您需要索引器,则必须围绕现有List<T>T[]编写自己的包装器。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

ICollection(非通用版本)仅获得IEnumerable + Count