向集合添加元素的方法

Ways of adding elements to collections

出于好奇,我看到了两种在 C# 中创建集合的方法。对我来说,这只是一种风格,但也许还有另一种解释。表现?这是否对应于一种模式?我在示例 2 中唯一能看到的是,它是一种防止覆盖集合的方法。

示例 1:

public class Employee
{
   ...
   public List<Phone> Phones
   {
      get; set;
   }
   ...
}

所以。来自另一个 class

Employee employee = new Employee();
employee.Phones = this.GetPhones();

示例 2:

public class Employee
{
   ...
   private List<Phone> colPhones;
   public List<Phone> Phones
   {
      get
      {
         if(this.Phones == null)
         {
             this.Phones = new List<Phone>();
         }
         return this.Phones;
      }
   }
   ...
   public void AddPhone(Phone phone)
   {
       this.Phones.Add(phone);
   }
}

所以。

Employee employee = new Employee();
List<Phone> phones = this.GetPhones();
//--> Here, I know I can use for(int i....) instead of foreach. This is just for the example.
foreach(Phone phone in phones) 
{
   employee.Phones.Add(phone);
}

更新:

我在阅读 Martin Fowler 的一本名为 "Refactoring" 的书时发现了这个 link Encapsulate collection,这与接受的答案的概念相同。

执行以下代码时,私有成员变量是在代码的 IL 级别向下创建的。

public List<Phone> Phones { get; set; }

第二种方法是一种实现延迟加载的方法。通常,不执行 this.Phones = new List<Phone>();,而是提供一种从数据库生成集合的方法。使用第二个场景的另一个原因是不覆盖任何现有集合,但在引用 属性.

时避免担心 NullReferenceExceptions

对于 95% 的情况,第一种情况都可以。

在这两个示例中,没有什么可以阻止您的员工 class 的消费者执行以下操作:employee.Phones.Add(new Phone())。除非你创建 属性 readonly,否则没有办法阻止修改集合,但是你只能在 Employee class 的构造函数中设置它,并且你的AddPhone() 方法将无法使用。

在我看来,您的第一个示例相当危险。你自己说它容易受到集合 "overwrite" 的影响,但我认为更重要的是,如果你不小心的话,它很容易受到集合的细微修改的影响。

Employee employee = new Employee();
List<Phone> obscureTemporaryVariable = this.GetPhones();
employee.Phones = obscureTemporaryVariable;
...
// much later, after having forgotten all about the above bit of code
obscureTemporaryVariable.Clear();
obscureTemporaryVariable.Add(new Phone(42));

现在您(可能是无意中)修改了 "employee" 的 phone 数字。