我们正在使用一个对 3D 测量数据执行计算的类库,它公开了一个方法:
MeasurementResults Calculate(IList<IList<Measurement>> data)
我想允许使用任何可索引的列表列表(当然是测量)调用此方法,例如:
Measurement[][] array;
List<List<Measurement>> list;
使用数组调用方法可以正常工作,这有点奇怪。这里有一些编译器技巧吗?尝试使用 List
调用会出现熟悉的错误:
cannot convert from 'List<List<Measurement>>' to 'IList<IList<Measurement>>'
因此,我编写了一个外观类(也包含其他一些东西),其中的方法将参数和方法之间的泛型定义分开,并在必要时转换为 IList 类型:
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);
}
这是解决问题的好方法,还是您有更好的主意?
此外,在测试问题的不同解决方案时,我发现如果类库方法是用 IEnumerable
而不是 IList
声明的,则可以调用同时使用数组和 List
的方法:
MeasurementResults Calculate(IEnumerable<IEnumerable<Measurement>> data)
我怀疑编译器又在起作用,我想知道为什么他们没有让 IList
与 List
一起工作?
最佳答案
可以用IEnumerable<T>
来做这个,因为 在 T
中是协变的。使用 IList<T>
这样做是不安全的,因为它同时用于“输入”和“输出”。
特别是,考虑:
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];
有关 generic covariance and contravariance 的更多信息,请参阅 MSDN .
关于c# - 列表的通用列表,将 List<List<T>> 转换为 IList<IList<T>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10229956/