views:

2987

answers:

3

I've got an OR mapper (iBatis.Net) that returns an IList.

// IList<T> QueryForList<T>(string statementName, object parameterObject);
var data = mapper.QueryForList<Something>(statement, parameters);

I'm trying to use it in an webservice an want to return the data 1:1. Of course I can't return IList in a WebMethod, because it is an interface and therefore not serializable.

I found that the mapper is really returning an List. But I'm afraid to cast it to List because of course the mappers inner workings could change in future versions (and it just feels dirty).

So should I ...

a) return new List<Something>(data);

b) return (List<Something>)data;

c) // your solution here

Thanks a lot!

A: 

I don't think you need a c). It should be pretty safe to use solution a).

This solution depends on the public api of IBatis.net. Good api's don't change their public api unless it's really the only solution to a mission critical problem

Hope this helps.

norbertB
The fact that the IList returned is a List is not part of the public API; this is the all point of using interfaces.
Luc Touraille
Not what i said. returning ilist is part of the public api
norbertB
norbertB, yes, solution a) is safe, but if the IList contains many elements it will be slow, also ... b) whould be the fastest but is not safe, hence my question for a solution c).
Hinek
+2  A: 

Why should you serialize IList :) Just use it as a source for your own collection and serialize it:

var data = mapper.QueryForList<T>(statement, parameters);
var yourList = new List<T>(data);
//Serialize yourList here ))
ProfyTroll
Because if the IList is already a List, it is faster to use it instead of pumping the items into a new List.
Hinek
+9  A: 

If it really is a List<T> but you want to protect against change and have it still work, then the most performant solution will be to attempt to cast it to a list, and if that fails then create a new list from its content, e.g.

var data = mapper.QueryForList<T>(statement, parameters);
var list = data as List<T> ?? new List<T>(data);

However, you mention that you can't return an interface because it's a web service. This may have been true with ASMX and the XmlSerializer class, but if you build the web service using WCF and use the DataContractSerializer then it will happily serialize collection interfaces (both as inputs to and outputs from the service). That type of change may be somewhat larger than you're looking for though!

Greg Beech
wow.. thats kool. i didnt know u could co that with WCF. rock on!
cottsak
Thank you! For this project I will not switch to WCF but it's good to know for future reference. Also I just recognized: I really love the ?? syntax ;-)
Hinek