【问题标题】:C# iterate generic objectC# 迭代泛型对象
【发布时间】:2013-06-29 19:46:02
【问题描述】:

我正在使用 C# 从 Excel VBA 迁移到 VSTO。在 VBA 中,我有一个名为 IsInCollection 的 3 行自定义函数,如下所示:

On Error Resume Next
Set obj = collectionObject(itemObject)
IsInCollection = Not (obj is Nothing)

我一直使用它来检查给定的工作簿是否打开,或者工作簿是否包含具有特定名称的工作表等。因为集合和项目参数被定义为对象,它可以与任何东西一起使用。

我正在尝试在托管代码中创建相同的实用程序函数/方法,并且正在苦苦挣扎。问题在于collectionObject(itemObject) 表达式。 C# 不允许我像 VBA 那样只索引对象。

如果有人能指出我正确的方向,将不胜感激。从我的搜索中,我一直在研究 QueryInterface,但不确定这是否是我应该寻找的地方。似乎 Excel 对象以System._ComObject 的形式出现,所以大概我需要以某种方式遍历它(?)。

TIA

【问题讨论】:

    标签: c# .net excel vsto


    【解决方案1】:

    我想你想看看 LINQ。例如,您可以查询像

    这样的集合
    IsInCollection = obj.Any(s => s != null);
    

    【讨论】:

    • 谢谢。我还没有真正理解 LINQ。我最初认为它只是一种“反向 SQL”,但我知道它还有很多。在上面的内容中,obj 必须等同于我的collectionObject,但我不确定.Anys 是否对应于我的itemObject。我尝试了几种变体都没有成功。我认为问题归结为弄清楚如何迭代作为对象传递的集合,当它可能是工作表、范围名称或数据透视项等的集合时。
    【解决方案2】:

    C# 中的索引运算符是 [],而不是 VB 中的 ()。不过我对 COM 不是很熟悉,所以如果您拥有的对象只是一个对象/System._ComObject,您可能必须先将其转换为适当的类型,除非 _ComObject 已经有一个索引器。

    似乎找出 _ComObject 的真正类型有点困难,所以你可能想试试我在http://www.mztools.com/articles/2006/mz2006013.aspx 找到的技巧:

    var typeName = Microsoft.VisualBasic.Information.TypeName( collectionObject );
    

    我还怀疑你可以使用 System.ComponentModel.TypeDescriptor 类。

    【讨论】:

    • 此外,无论结果如何,都希望有一个 .Contains 方法,该方法应该比尝试访问某个项目但无法访问某个项目更容易/更整洁。
    • 谢谢。 var typename 是一个巧妙的技巧,但在这种情况下它并没有帮助我。问题似乎是该对象可能是工作簿、范围名称或数据透视字段等的集合。我无法在.NET 中找到一种方法来枚举作为对象传入的某些内容。关于括号,我的问题有点误导 - 我知道 C# 中使用了方括号。感谢您提供有关 .Contains 方法的提示。我实际上已经在使用它 - 在第一次尝试(不成功!)将对象转换为数组或 List.
    • 呵呵,我只是懒得打出“字符串”。无论如何,即使 excel 返回不同事物的集合,我认为它会是一些集合类而不是数组。如果你能找到正确的类型,我相信你可以让演员工作。您是否检查了文档以获取您用来获取集合的方法/属性?
    猜你喜欢
    • 1970-01-01
    • 2022-01-19
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 2012-02-27
    • 2019-07-19
    • 1970-01-01
    • 2010-09-05
    相关资源
    最近更新 更多