Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
386 views
in Technique[技术] by (71.8m points)

c# - WCF OperationContract - which generic collection type should I expose?

I have a WCF web service that has a method that returns a generic collection. Now, my question is: Should I expose it as ICollection<T>, List<T>, IList<T>, IEnumerable<T> or something else?

I suppose that List<T> is out of the question since I want to avoid CA1002 errors, but the underlying type will be a List<T>.

I am really interested in hearing your takes on this, preferably with a good explanation of why you think what you think.

Thanks in advance

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Keep in mind that errors such as CA1002 are really meant to apply to libraries. A WCF service is not a library, it's an endpoint that's serializing everything over SOAP, REST, etc.

You'll find that if you try to expose an interface such as ICollection<T> or IList<T>, you'll get errors that the type can't be serialized. In fact, List<T> is probably the best choice here. When a proxy gets generated on the client side, it ends up as an array by default, and many if not most people change it to a List<T>, so 90% of the time, no matter how you choose to expose it, that's the type that the client is going to see anyway.

I'll note that it's generally good practice not to "return" a collection at all from a WCF operation or a web service in general. It's more common to create a proxy class that contains the collection you want, and return that, i.e.:

[OperationContract]
OrdersResult GetOrders(OrderRequest request);

Where the proxy class might look like this:

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

That way if you decide you need to add more data to either the request or the response, you can do so without causing breaking changes to the client.


Addendum: The real issue here with WCF is that WCF doesn't know that a particular type is used only for outbound data. When any class is exposed through a WCF service, WCF assumes that it can be part of either a request or a response, and if it is part of a request, then the type must be concrete and cannot be immutable. That's the reason for all the other silly restrictions like requiring property setters.

You simply have no choice here but to use a concrete, mutable collection type, and in most cases that means either an array or a generic list.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...