【问题标题】:Why is a typed .NET array not a generic type? (i.e. SomeType[] != Array{SomeType})为什么类型化的 .NET 数组不是泛型类型? (即 SomeType[] != Array{SomeType})
【发布时间】:2015-08-28 16:00:51
【问题描述】:

[背景:] 为了使针对 Excel 的互操作 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[] 如何不仅仅是 Array{ListObject} 的语法糖?

【问题讨论】:

    标签: c# excel extension-methods com-interop excel-interop


    【解决方案1】:

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

    现在,每个数组都派生自 Array 类型 - 但是,如果没有泛型(不可用),就无法实现类型安全,更不用说性能影响了。因此,数组介于原始类型和派生自 Array 的类之间。

    当然,最后,T[]Array&lt;T&gt; 之间没有任何有意义的区别——事实上,你可以说数组从一开始就是泛型的,早在实现“正确”泛型之前。

    List&lt;T&gt; 是一个完全独立的类——它只是在内部使用T[] 来存储实际数据。它的非泛型对应物是 ArrayList - 再次,在泛型进入语言和 CLR 之前创建。

    最后,您不必再为难了——LINQ 扩展方法对您不起作用的原因是,像ListObjects 这样的集合没有实现IEnumerable&lt;ListObject&gt;,而只有IEnumerable。 .NET 的设计者当然意识到了这一点,因此您可以根据需要轻松转换可枚举 - 例如,listObjects.OfType&lt;ListObject&gt;().Where(i =&gt; ...)。无需编写自己的扩展方法;)

    【讨论】:

    • 是的,我想我已经知道了。这是一个丑陋的不一致,但至少它是嵌入式互操作类型的通用集合的漏洞。谢谢。
    • @CarlFriedRiceGauss @CarlFriedRiceGauss 这个问题在stackoverflow.com/questions/1765685/… 中得到了很好的解释——你可以关闭嵌入,或者使用其他技巧:)
    猜你喜欢
    • 2012-12-28
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多