c# - 列表的通用列表,将 List<List<T>> 转换为 IList<IList<T>>

标签 c# .net generics ienumerable ilist

我们正在使用一个对 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)

我怀疑编译器又在起作用,我想知道为什么他们没有让 IListList 一起工作?

最佳答案

可以用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/

相关文章:

generics - 是否有语言在作为参数传递的函数上实现保留泛型?

c# - C# 中的 PDF 审阅器(ASP.NET/Silverlight?)

.net - 字典与 KeyPairValue 的使用

c# - 我怎样才能在这里使用泛型

java - 创建未知类型的数组

c# - .Net 控制台应用程序作为 CLI 命令

c# - 如何在使用过滤器时获取 CollectionView 的真实计数?

C# DateTime 不改变

c# - "bad"在.NET中使用try-catch进行流控?

c# - 将控件视为 ComboBox 或 TextBox