在API代码中,为列表类型C#属性使用私有setter是一个好主意吗?

Dav*_*lls 2 c# setter properties private list

我正在寻找一些关于某事的意见.请考虑以下来自名为的类的代码SomeApiObject:

// Property with private setter
public IList<string> SomeList
{
    get;
    private set;
}

// Constructor
public SomeApiObject()
{
    SomeList = new List<string>();
}
Run Code Online (Sandbox Code Playgroud)

有了这个设置,类的用户SomeApiObject不能重新分配SomeList财产,但他们可以做的是通过使用诸如操纵现有列表Add(),Remove()Clear().

这种模式的好处是保证属性永远不会出现null,这可以是一个非常方便的假设,因为用户正在使用API​​,因为这意味着用户可以总是迭代列表,获取列表的大小,或添加到它而无需检查null.

我看到一些缺点.例如,对于用户来说,通过操纵其内容可以写入该列表并不一定是显而易见的.另一方面,我可以设想,操作列表在语法上不太方便,或者在性能上可能比分配新列表更差.

我和这个人在一起,我正在征求意见.

  • API的用户潜在的缺点是否过于令人讨厌?
  • 保证永远不会null像我想的那样漂亮吗?

编辑:

我已经确信使用某种"永不空"模式的好处.我更感兴趣的是有人扮演魔鬼的拥护者,并告诉我为什么在API的用户的角度来看,在列表上设置一个私人的二传手可能会令人讨厌和/或禁止.

我不久前发布了一个.NET API包装器,到目前为止,一些用户对如何为这样的属性赋值给出了混淆.

bry*_*ook 5

Never null是一个很好的设计功能.关于仅将列表显示为只读属性,这在我最喜欢的指南书中作为建议提出:http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321545613

虽然更好的方法是不允许外部调用者直接操作对象的状态并使类不可变:

public class MyClass
{
   private List<string> _inner = new List<string>();

   public IEnumerable<string> Items
   {
      get { return _inner.GetEnumerator(); }
   }

   public void AddItem(string item);
   {
      _inner.Add(item);
   }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常好的答案.我喜欢露骨; 它不要求类的用户通过检查每个属性的类型来推断意图. (2认同)