【问题标题】:Is there a need to encapsulate Collections?是否需要封装集合?
【发布时间】:2011-05-06 16:45:06
【问题描述】:

是否需要封装 Collections?

private List<Item> items;

public Items Items
{
    get { return this.items; }
    set { this.items= value; }
}

或者只是

public List<Item> Items;

编辑:

  • 有没有办法在不暴露公共 getter 的情况下绑定到集合?

【问题讨论】:

    标签: .net oop collections encapsulation


    【解决方案1】:

    创建一个自定义集合来包装标准集合以便您可以控制调用者的操作是最佳选择,但是它有成本

    我认为这取决于有多少不同人将针对您的对象模型编写代码,以及这些人是否与您属于同一团队。 p>

    您通过封装您的集合来阻止调用者做“坏事”;这可能会节省调用者的调试时间,也让调用者更容易弄清楚如何使用你的 API。

    所以这是你的时间和将使用你的对象模型的程序员的时间之间的交易。

    【讨论】:

      【解决方案2】:

      建议您不要将集合属性设置器公开;请参阅 MSDN 上的 this rule。更好的做法是只公开接口而不是具体类型。

      class Example
      {
           public Example()
           {
               this.MyList = new List<string>();
           }
      
           public IList<string> MyList { get; private set; }
      }
      

      【讨论】:

        【解决方案3】:

        公开收藏是一个非常糟糕的主意。虽然封装字段在任何情况下都很重要,但集合更为重要。

        集合本身通常不是你真正关心的对象。所以你的类的调用者不应该能够设置它、替换它甚至拿走它(比如:设置为null)。它应该只关心其中的项目。如果您可以从外部设置列表实例,则您的类的多个实例可能会共享同一个列表实例。这会产生一些令人讨厌的副作用。

        您的班级(至少)负责创建列表实例,以确保它是专用列表,而不是空引用。

        通过公共 getter 公开列表实际上就像完全公开它一样。这是您应该做的最小封装,实际上就像根本没有封装一样。

        完全封装仅通过将项目公开为IEnumerable 并在单独的方法或属性中提供添加、删除、计数和类似操作来完成。你需要的越多,它就越复杂。如果您确实不需要从外部进行许多基本操作并尽可能在类内进行管理,则它很有用。

        【讨论】:

        • 一些我需要绑定到myObject.Items,所以我需要外部化集合。
        • 在这种情况下,您仍然可以操作该集合。 Items.Clear()、Items.Add、Items.Remove 等...
        • “将项目公开为 IEnumerable” - 您始终可以将其转换为初始 List&lt;Item&gt;
        • @serhio:你永远无法避免滥用某些东西。 IMO,封装与“安全”无关,以避免任何人做坏事。这只是为了说明它打算如何使用。您也可以使用反射来更改私有字段...但是您知道该类不打算像这样使用。
        • @Stefan Steinegger:我不确定如果暴露为IEnumerable,该集合仍然是可写绑定的......
        【解决方案4】:

        一般来说,公共领域在 .NET 世界中是不受欢迎的。此外,来自方法或属性的returning null collections 也令人不悦。因此,我肯定会“封装”这个集合。

        【讨论】:

          【解决方案5】:

          有时我会这样连接它......

          List<Item> _items;
          public Items Items
          {
              get 
              {
                  if (_items == null) _items = new List<Items>();
                  return _items;
              }
              private set { _items = value; }
          }
          

          【讨论】:

            【解决方案6】:

            .net 中有一个标准,新实例化的对象初始化其集合以最小化空引用。您会注意到大多数框架库都遵循这一点。

            public class PotOfUnicorns
            {
            
                private List<Item> items = new List<Item>();
            
                public Items Items
                {
                    get { return this.items; }
                    private set { this.items= value; }
                }
            
            }
            

            【讨论】:

              【解决方案7】:

              我通常将集合公开为只读。通常没有理由分配新集合。我将在构造函数或属性 getter 中实例化一次集合。这减少了空引用错误的可能性。

              【讨论】:

              • +1,将集合暴露给修改几乎总是一个坏主意,而不是你想要的。您可能希望公开一个方法以添加到集合(或从中删除),但控制整个集合通常并不好。
              • “这减少了空引用错误的可能性。”我认为方法对所有班级成员都是通用的,而不是专门针对集合。
              • IMO,不仅“没有理由分配新集合”,它还可能产生副作用。看我的回答。
              猜你喜欢
              • 1970-01-01
              • 2016-08-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多