代码之家  ›  专栏  ›  技术社区  ›  Prashant Cholachagudda

如何限制将项目添加到列表<T>?

  •  4
  • Prashant Cholachagudda  · 技术社区  · 17 年前

    我有课要上课 Person 包含属性、父项和子项列表。

    我希望每个人都只使用 AddChild 方法来添加子项,而不是 List.Add

    public class Person
    {
      private List<Person> _children = new List<Person>();
      public string Name { get; set; }
      public Person Father { get; set; }
      public List<Person> Children 
      { 
        get
        {
           return _children;
        } 
      }
      public void AddChild(string name)
      {
          _children.Add( new Person { Name = name, Father = this });
      }
    }
    
    7 回复  |  直到 17 年前
        1
  •  12
  •   Pawel Lesnikowski    17 年前

    将子项公开为只读集合:

    public IList<Person> Children  
    {  
        get 
        { 
           return new ReadOnlyCollection<Person>(_children);
        }  
    } 
    
        2
  •  8
  •   Thomas Weller    17 年前

    public IList<Person> Children 
    { 
      get
      {
         return _children.AsReadOnly();
      } 
    }
    
        3
  •  8
  •   Matthew Scharley    17 年前

    暴露 Children IEnumerable<T>

        4
  •  7
  •   Marc Gravell    17 年前

    如果您正在暴露底层 List<T>

    您可以编写自己的集合包装器类,或者从 Collection<T> (这仍然暴露了 Add ,但你可以 override 在添加数据之前,有几件事需要检测)。

        5
  •  3
  •   devnull    17 年前

    将Children属性公开为 ReadOnlyCollection<Person>

    public ReadOnlyCollection<Person> Children
    {
         get {return _children.AsReadOnly();}
    }
    
        6
  •  3
  •   chwarr Tamas Hegedus    12 年前

    如果您使用的是.NET 4.5或更高版本,则可以返回 _children 像 IReadOnlyList<T>

    public IReadOnlyList<Person> Children
    {
        get
        {
            return _children;
        }
    }
    

    这与返回 IList<Person> 通过 _children.AsReadOnly() ? IReadOnlyList<Person> 甚至没有突变的方法。考虑下面的代码:

    somePerson.Children[0] = null;
    

    使用时 IReadOnlyList<人> 此代码将无法编译。使用时 .AsReadOnly() 此代码将导致运行时异常。

    这与返回 ReadOnlyCollection<Person> 通过 _children.AsReadOnly() ? 没有 只读集合<人> 已创建包装器对象。除此之外,我看不出有什么大的不同。

        7
  •  2
  •   Wedge    17 年前

    IEnumerable可以很好地工作:

    public IEnumerable<Person> Children
    {
        get
        {
            return _children.AsReadOnly();
        }
    }
    

    或者更冗长的:

    public IEnumerable<Person> Children
    {
        get
        {
            foreach (Person child in _children)
            {
                yield return child;
            }
        }
    }