Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way of using List<T> and exposing Collection<T>

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)

like image 302
alexandrul Avatar asked Oct 13 '08 13:10

alexandrul


2 Answers

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.

like image 131
Marc Gravell Avatar answered Nov 15 '22 17:11

Marc Gravell


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.

like image 40
Joe Avatar answered Nov 15 '22 18:11

Joe