使用 List<T> 和公开 Collection<T> 的最佳方式

Posted

技术标签:

【中文标题】使用 List<T> 和公开 Collection<T> 的最佳方式【英文标题】:Best way of using List<T> and exposing Collection<T> 【发布时间】:2008-10-13 13:01:43 【问题描述】:

我必须实现一个公开值列表(整数、自定义类等)的 Web 服务。 我的工作解决方案返回 List&lt;T&gt;,根据 FxCop 的说法,最好返回 Collection&lt;T&gt;ReadOnlyCollection&lt;T&gt;

如果我选择返回 ReadOnlyCollection&lt;T&gt;,Web 服务会显示如下错误:

要实现 XML 可序列化,从 ICollection 继承的类型必须在其继承层次结构的所有级别上实现 Add(System.Int32)System.Collections.ObjectModel.ReadOnlyCollection1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] 没有实现Add(System.Int32)

您最喜欢在内部使用 List&lt;T&gt; 并公开 Collection&lt;T&gt; 的方式是什么? (使用 C#,最好只使用 framework 2.0)

【问题讨论】:

【参考方案1】:

List 或 Collection 在这种情况下很好。

就原始问题而言,您可以非常简单地将 List 包装在 Collection 中:

List<Foo> list = new List<Foo>();
// ...
Collection<Foo> col = new Collection<Foo>(list);

这是一个真正的包装器;将一个项目添加到包装器(col),它被添加到列表中。这可能有点令人困惑,因为许多这样的构造函数使用参数来进行初始填充,但不链接到原始列表。 Collection 是一个例外;-p

由于您处于 Web 服务边界,因此 FxCop 的建议不适用。这对于防止调用者踩踏被调用者的内存很有用(与Eric Lippert's recent blog 内联) - 但在 Web 服务分布式场景中根本不适用。事实上,由于 Web 服务在某些通用场景中存在一些有据可查的问题,因此可以说一个简单的数组在 Web 服务边界上非常有用和实用。在 Eric 博客的上下文中 - 在这种情况下,调用者/被调用者问题没有问题,因为两者之间存在强制障碍。

就 WSDL/mex 而言,我怀疑所有 3 个(列表/集合/数组)都将成为一个元素块 - 所以你可以选择最方便的那个。

【讨论】:

感谢您的回答以及有关 Collection 作为真正包装器的详细信息,我之前没有找到任何关于它的信息。【参考方案2】:

我通常从 WCF Web 服务返回 IList:FxCop 对此非常满意。 不确定这是否适用于 ASMX Web 服务。

【讨论】:

ASMX Web 服务不会序列化(并且会给出运行时异常)接口。

以上是关于使用 List<T> 和公开 Collection<T> 的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

STL 之copy()

使用 DbContext Set<T>() 而不是在上下文中公开

Stream的去重排序

使用和声明泛型 List<T>

T[] 和 List<T> 有啥区别?

模型 List<T> 和 ViewModel ObservableCollection<T> 重复数据?