使用 List<T> 的最佳方法和暴露 Collection<T> 的方式

8
我必须实现一个Web服务来公开一系列值(整数,自定义类等)。我的工作方案返回一个List<T>,根据FxCop的建议,最好返回一个Collection<T>ReadOnlyCollection<T>
如果我选择返回一个ReadOnlyCollection<T>,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<T>并公开Collection<T>?(使用C#,最好仅使用框架2.0)
2个回答

14

在这种情况下,List<T> 或 Collection<T> 都可以。

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

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

这是一个真正的包装器;将一个项目添加到包装器(col)中,它就会被添加到列表中。这可能有点令人困惑,因为许多这样的构造函数使用参数来进行初始填充,但不链接到原始列表。Collection<T>是一个例外 ;-p 由于您处于Web服务边界上,FxCop的建议不适用。这很有用(与Eric Lippert最近的博客一致),以防止调用者践踏被调用者的内存——但在Web服务分布式场景中,这根本不适用。事实上,由于Web服务存在某些特定的泛型场景问题,一个简单的数组在Web服务边界上可以说非常可用和实用。在Eric的博客背景下,在这种情况下,没有调用者/被调用者的问题,因为两者之间有强制性的障碍。
在WSDL/mex方面,我怀疑所有3个(列表/集合/数组)都将成为一个元素块,因此您可以选择最方便的那个。

谢谢你的回答和关于Collection作为真正封装器的详细说明,我之前没有找到相关信息。 - alexandrul

1

我通常从WCF web服务返回IList<T>:FxCop对此感到满意。 不确定这是否适用于ASMX web服务。


ASMX Web服务不能序列化(并且会导致运行时异常)接口。 - Jesse C. Slicer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接