10

我有一个 WCF Web 服务,它有一个返回泛型集合的方法。现在,我的问题是:我应该将其公开为ICollection<T>, List<T>,IList<T>还是IEnumerable<T>其他?

我想这List<T>是不可能的,因为我想避免CA1002 错误,但基础类型将是 a List<T>

我真的很想听听你对此的看法,最好能很好地解释你为什么这么想。

提前致谢

4

2 回答 2

18

请记住,诸如 CA1002 之类的错误确实适用于库。WCF 服务不是一个库,它是一个通过 SOAP、REST 等序列化所有内容的端点。

你会发现,如果你尝试暴露一个接口如ICollection<T>or IList<T>,你会得到类型不能被序列化的错误。事实上,List<T>这里可能是最好的选择。当在客户端生成代理时,默认情况下它会以数组的形式结束,如果不是大多数人的话,很多人会将其更改为 a List<T>,因此 90% 的时间,无论您选择如何公开它,这就是无论如何,客户都会看到。

我会注意到,通常最好不要从 WCF 操作或 Web 服务中“返回”集合。更常见的是创建一个包含您想要的集合的代理类,然后返回它,即:

[OperationContract]
OrdersResult GetOrders(OrderRequest request);

代理类可能如下所示:

[DataContract]
public class OrdersResult
{
    [DataMember]
    public List<Order> Orders { get; set; }
}

这样,如果您决定需要向请求或响应中添加更多数据,则可以这样做而不会对客户端造成重大更改。


附录:WCF 的真正问题是WCF 不知道特定类型仅用于出站数据。 当任何类通过 WCF 服务公开时,WCF 假定它可以是请求响应的一部分,如果它是请求的一部分,则类型必须是具体的并且不能是不可变的。这就是要求属性设置器等所有其他愚蠢限制的原因。

您在这里别无选择,只能使用具体的、可变的集合类型,在大多数情况下,这意味着数组或泛型列表。

于 2010-02-19T14:54:48.917 回答
6

在我看来,暴露序列的服务和数据合约应该清楚地表明这些序列是不可变的,因为它们作为DTO在网络上传输。在您从不同层收到的序列上添加和删除没有多大意义。相反,您想读取该数据并对其进行处理。

鉴于此,我真的更喜欢使用IEnumerable<T>,但不幸的是,这不适用于 WCF。您可能会遇到各种奇怪的错误,尤其是在延迟执行方面,因此(在 WCF 上下文中)最好远离这些错误。

那真的只剩下arrays,因为它们在其余选项中最好地传达意图。

于 2010-02-19T14:56:49.183 回答