We're using a class library that performs calculations on 3D measurement data, it exposes a method:
MeasurementResults Calculate(IList<IList<Measurement>> data)
I would like to allow calling this method with any indexable list of lists (of Measurement of course), for example both:
Measurement[][] array;
List<List<Measurement>> list;
Calling the method using the array works fine, which is a bit strange. Is there some compiler trick at work here? Trying to call with the List
gives the familiar error:
cannot convert from 'List<List<Measurement>>' to 'IList<IList<Measurement>>'
So, I have written a facade class (containing some other things as well), with a method that splits the generic definition between the argument and method and converts to the IList type if necessary:
MeasurementResults Calculate<T>(IList<T> data) where T : IList<Measurement>
{
IList<IList<Measurement>> converted = data as IList<IList<Measurement>>;
if(converted == null)
converted = data.Select(o => o as IList<Measurement>).ToList();
return Calculate(converted);
}
Is this a good way to solve the problem, or do you have a better idea?
Also, while testing different solutions to the problem, I found out that if the class library method had been declared with IEnumerable
instead of IList
, it is ok to call the method using both the array and the List
:
MeasurementResults Calculate(IEnumerable<IEnumerable<Measurement>> data)
I suspect that there is some compiler trick at work again, I wonder why they haven't made IList
work with List
while they were at it?
It's okay to do this with IEnumerable<T>
, because that is covariant in T
. It wouldn't be safe to do that with IList<T>
, as that is used for both "input" and "output".
In particular, consider:
List<List<Foo>> foo = new List<List<Foo>>();
List<IList<Foo>> bar = foo;
bar.Add(new Foo[5]); // Arrays implement IList<T>
// Eh?
List<Foo> firstList = foo[0];
See MSDN for more information about generic covariance and contravariance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With