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



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

我刚刚为ListObjects接口创建了一些扩展方法,它们给了我编译器错误,"程序集Y.dll中的成员X不能跨程序集边界使用,因为它包含一个具有嵌入互操作类型的泛型类型参数的类型。">

以下是导致错误的方法:

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[]如何不仅仅是数组{ListObject}的语法糖?

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

现在,每个数组都是从类型Array派生的——然而,如果没有泛型(不可用(,就无法实现类型安全,更不用说性能影响了。因此,数组介于基元类型和从Array派生的类之间。

当然,最终,T[]Array<T>之间没有什么有意义的区别——事实上,你可以说数组从一开始就是泛型的,早在实现"正确"的泛型之前。

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

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

最新更新