为什么类型化的 .NET 数组不是泛型类型? (即 SomeType[] != Array{SomeType})

Why is a typed .NET array not a generic type? (i.e. SomeType[] != Array{SomeType})

[背景:] 为了使针对 Excel 的互操作 API 的编程更容易,我为常见任务创建了许多扩展方法。其中许多是 Excel 的集合对象(如 Workbooks、Sheets 等)的 LINQ 样式方法。所有扩展方法都在一个程序集中,我在任何需要这些方法的应用程序或加载项中引用该程序集.扩展方法程序集和目标应用程序都嵌入了来自同一个主互操作程序集的互操作类型。一切都是在 .NET 4.0 上用 C# 编写的,并引用了 PIA 版本 15。

我刚刚为 ListObjects 接口创建了一些扩展方法,它们给我编译器错误,"Member X from assembly Y.dll cannot be used across assembly boundaries because it contains a type which has a generic type parameter that is an embedded interop type."

这里是导致错误的方法:

public static IEnumerable<ListObject> Where(this ListObjects me,Func<ListObject, Boolean> condition) {
    var list = new List<ListObject>();
    foreach (ListObject x in me)
        if (condition(x)) list.Add(x);
    return list;
}

这是一个类似的有效方法:

public static IEnumerable<Workbook> Where(this Workbooks me, Func<Workbook, Boolean> condition) {
    var list = new List<Workbook>();
    foreach (Workbook x in me)
        if (condition(x)) list.Add(x);
    return list;
}

为什么一个可以跨程序集边界工作而另一个不能?


更正,这两种方法都不适用于该特定应用程序。但是,我能够通过为 ListObjects 创建 ToArray() 扩展方法,然后在我的应用程序中调用它并在数组上调用 LINQ 方法来获得所需的结果。

为什么强类型列表不算作泛型?

为什么 ListObject[] 不仅仅是 Array{ListObject} 的语法糖?

嗯,最浅显的答案很简单——当数组被添加到语言中时,没有泛型。

现在,每个数组都派生自类型 Array - 然而,如果没有泛型(当时不可用),将无法实现类型安全,更不用说性能影响了。因此,数组介于原始类型和派生自 Array.

的 class 之间。

当然,最终,T[]Array<T> 之间没有任何有意义的区别 - 事实上,您可以说数组从一开始就是通用的,早在 [=31] 之前=] 实现了泛型。

List<T> 是一个完全独立的 class - 它只是在内部使用 T[] 来存储实际数据。它的非泛型对应物是 ArrayList - 同样,在泛型进入语言和 CLR 之前创建。

最后,您不需要经历这些困难 - LINQ 扩展方法对您不起作用的原因是像 ListObjects 这样的集合没有实现 IEnumerable<ListObject>,但只有 IEnumerable。 .NET 的设计者当然意识到了这一点,因此您可以轻松地适当地转换可枚举 - 例如,listObjects.OfType<ListObject>().Where(i => ...)。无需编写自己的扩展方法 ;)