views:

1229

answers:

2

I must implement a web service which expose a list of values (integers, custom classes etc). My working solution returns a List<T>, and according to FxCop it is better to return a Collection<T> or ReadOnlyCollection<T>.

If I choose to return a ReadOnlyCollection<T>, the web service shows an error like:

To be XML serializable, types which inherit from ICollection must have an implementation of Add(System.Int32) at all levels of their inheritance hierarchy. System.Collections.ObjectModel.ReadOnlyCollection 1 [[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] does not implement Add(System.Int32).

What is your favorite way to use internally a List<T> and expose a Collection<T> ? (using C#, and preferably framework 2.0 only)

+13  A: 

List<T> or Collection<T> are fine in this case.

In terms of the original question, you can wrap a List<T> in a Collection<T> very simply:

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

This is a true wrapper; add an item to the wrapper (col), and it gets added to the list. This can be slightly confusing, because many such constructors use the argument to do the initial population, but don't link to the original list. Collection<T> is an exception ;-p

Since you are on a web-service boundary, that recommendation from FxCop doesn't apply. That is useful (inline with Eric Lippert's recent blog) to prevent a caller stomping over the callee's memory - but in a web-service distributed scenario that simply doesn't apply. In fact, since web-services have a few well documented issues with certain generic scenarios, a simple array is arguably very usable and pragmatic at a web-service boundary. In the context of Eric's blog - in this case, there is no question of the caller/callee issue, since there is an enforced barrier between the two.

In terms of WSDL/mex, I suspect all 3 (list/collection/array) will just become a block of elements - so you may a well go with whichever is most convenient.

Marc Gravell
Thank you for your answer and for the details about Collection acting as a true wrapper, I did not find anything about it before.
alexandrul
+1  A: 

I usually return IList<T> from a WCF web service: FxCop is happy enough with this. Not sure if this works with ASMX web services.

Joe
ASMX web services won't serialize (and will give a run-time exception) interfaces.
Jesse C. Slicer