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?
IList<IList<T>>
method with aT[][]
works because of broken array covariance. It is broken because the compiler would allow you to assign aList<T>
to an element of theIList<IList<T>>
, but if the object is really aT[][]
, the assignment will fail at run time. – Orvieto