当属性可以合法地为null时,我应该如何将通用List <t>公开为.NET API中的属性?</t>

时间:2012-10-30 22:51:42

标签: c# fxcop api-design

我正在尝试创建一个.NET API,它包装并与第三方C API接口。因此,API的语义如下:

有一个属性表示二进制文件中的字符串列表。在具有零条目的列表的此属性之间存在区别,在这种情况下,该属性将被写入具有空列表的文件;并且列表被完全省略,在这种情况下,属性将从文件中省略。

在我目前的设计中,我使用的是这样的东西:

public class InfoWrapper
{
    // Use an IList<T> to avoid running afoul of FxCop
    // rule CA1002: Do not expose generic lists.
    public IList<string> ItemsContainer { get; set; }
}

当然,这样做可以让我区分“未设置”和“空列表”情况,但真正的问题是它会触发另一个FxCop警告,CA2227:集合属性应该是只读的。我需要能够允许用户将属性设置为null值,如果他们在将其设置为null后改变主意,则可能会返回列表。我可以使用一对方法(例如,DeleteItemsContainer()CreateNewItemsContainer())将属性设置为只读,但实际上,我需要以相同的方式处理这些属性中的几个。每个属性添加两个方法会大大混乱API。这里有什么更好的方法?

N.B。我意识到我可以压制FxCop警告并完成它,并且这些规则只是一组建议。但是,如果可能的话,我希望保持这些准则。

2 个答案:

答案 0 :(得分:1)

我认为你混淆(或询问)两个问题:返回null与空集合,以及让公共setter触发FxCop警告。无论类型是null还是List,您都可以返回IList,因此没有问题。

如果您想避免关于公共setter的FxCop警告,您需要将setter设为私有,并提供另一种设置该属性值的方法。您可以通过IList的构造函数传递InfoWrapper,或者如果有意义,只需在构造函数中创建列表并在构造之后将所有项添加到其中。

答案 1 :(得分:0)

首先,属性必须是只读的,即没有setter。但即便如此,您仍会收到另一个FxCop警告,因为用户仍然可以修改该集合。

摆脱FxCop警告的一种简洁方法是将属性的定义从返回IList<T>更改为返回IEnumerable<T>

像这样:

public IEnumerable<string> StringList { get; set; }

如果您可以不使用Count等属性和索引器,则使用IEnumerable有助于确保类用户不会弄乱列表内容。

(顺便说一句,在命名属性时,建议不要使用术语“String”或“List”。“String”不表示属性的语义,“List”表示应该是的集合类型封装的)