Excel互操作:_Worksheet或工作表?

Jon*_*eet 74 c# com excel interop

我现在正在写关于动态类型的文章,我给出了一个Excel互操作的例子.我之前几乎没有做任何Office互操作,它显示了.C#4 的MSDN Office Interop教程使用了_Worksheet界面,但也有一个Worksheet界面.我不知道有什么区别.

在我荒谬简单的演示应用程序(如下所示)中,要么工作正常 - 但如果最佳实践指示一个或另一个,我宁愿适当地使用它.

using System;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;

class DynamicExcel
{
    static void Main()
    {
        var app = new Excel.Application { Visible = true };
        app.Workbooks.Add();

        // Can use Excel._Worksheet instead here. Which is better?
        Excel.Worksheet workSheet = app.ActiveSheet;

        Excel.Range start = workSheet.Cells[1, 1];
        Excel.Range end = workSheet.Cells[1, 20];
        workSheet.get_Range(start, end).Value2 = Enumerable.Range(1, 20)
                                                           .ToArray();
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图避免深入研究COM或Office互操作性,只是强调C#4的新功能 - 但我不想做任何真正的,真的愚蠢的事情.

(在上面的代码中可能还有一些非常,非常愚蠢的东西,在这种情况下请告诉我.使用单独的开始/结束单元而不仅仅是"A1:T1"是故意的 - 它更容易看出它真的是一个范围20个细胞.其他任何东西都可能是偶然的.)

那么,我应该使用_Worksheet或者Worksheet,为什么?

Eri*_*ert 77

如果我没记错的话 - 我对此的记忆有点模糊,自从我把Excel PIA分开以来已经很久了 - 就像这样.

事件本质上是一个对象在发生事件时调用的方法.在.NET中,事件是委托,简单明了.但是在COM中,将一大堆事件回调组织到接口中是很常见的.因此,您在给定对象上有两个接口 - "传入"接口,您希望其他人呼叫您的方法,以及"传出"接口,您希望在事件发生时调用其他人的方法.

在非托管元数据(类型库)中,对于可创建对象,有三个定义:传入接口,传出接口和coclass,它们表示"我是一个可创建的对象,它实现了这个传入接口,这个传出界面".

现在,当类型库自动转换为元数据时,遗憾的是,这些关系得以保留.拥有一个手工生成的PIA可以更好地使类和接口更符合我们在托管世界中的预期,但遗憾的是,这并没有发生.因此,Office PIA充满了这些看似奇怪的重复,其中每个可创建对象似乎都有两个与之关联的接口,其上有相同的东西.其中一个接口表示coclass的接口,其中一个接口表示该coclass的传入接口.

_Workbook接口是工作簿coclass上的传入接口.Workbook接口是表示coclass本身的接口,因此继承自_Workbook.

长话短说,如果你方便的话,我会使用Workbook; _Workbook是一个实现细节.


JP *_*oto 25

如果你看一下PIA程序集(Microsoft.Office.Interop.Excel)Reflector,Workbook接口就有了这个定义......

public interface Workbook : _Workbook, WorkbookEvents_Event
Run Code Online (Sandbox Code Playgroud)

Workbook_Workbook,但增加了事件.同样的Worksheet(抱歉,只是注意到你没有谈论Workbooks)......

public interface Worksheet : _Worksheet, DocEvents_Event
Run Code Online (Sandbox Code Playgroud)

DocEvents_Event ...

[ComVisible(false), TypeLibType((short) 0x10), ComEventInterface(typeof(DocEvents),
                     typeof(DocEvents_EventProvider))]
public interface DocEvents_Event
{
    // Events
    event DocEvents_ActivateEventHandler Activate;
    event DocEvents_BeforeDoubleClickEventHandler BeforeDoubleClick;
    event DocEvents_BeforeRightClickEventHandler BeforeRightClick;
    event DocEvents_CalculateEventHandler Calculate;
    event DocEvents_ChangeEventHandler Change;
    event DocEvents_DeactivateEventHandler Deactivate;
    event DocEvents_FollowHyperlinkEventHandler FollowHyperlink;
    event DocEvents_PivotTableUpdateEventHandler PivotTableUpdate;
    event DocEvents_SelectionChangeEventHandler SelectionChange;
}
Run Code Online (Sandbox Code Playgroud)

我想说最好用Worksheet,但这就是区别.


bar*_*owc 8

仅供内部使用的类和接口

避免直接使用以下任何类和接口,这些类和接口在内部使用,通常不直接使用.

类/接口:示例

classid类:ApplicationClass(Word或Excel),WorksheetClass(Excel)

classid事件x _SinkHelper: ApplicationEvents4_SinkHelper(Word),WorkbookEvents_SinkHelper(Excel)

_classid:_Application(Word或Excel),_工作表(Excel)

classid事件x:ApplicationEvents4(Word),AppEvents(Excel)

我是classid事件x: IApplicationEvents4(Word),IAppEvents(Excel)

http://msdn.microsoft.com/en-gb/library/ms247299(office.11​​).aspx

编辑:(重新:格式化此答案)无法正确格式化转义下划线,紧接着是斜体文本.在预览中正确显示但在发布时损坏

edit2:如果你使下划线本身斜体,这在概念上是可怕的,但我认为看起来是一样的


Joe*_*son 7

在过去的几年里,我已经看到并编写了相当多的C#/ Excel COM Interop代码,我看到几乎在所有情况下都使用了Workheet.我从来没有见过微软关于此主题的任何决定性内容.


Nol*_*rin 6

MSDN显示该Worksheet接口只是继承自_WorksheetDocEvents_Event接口.似乎只是提供了工作表对象可能引发的事件,而不是其他所有事件.据我所知,Worksheet不提供任何其他成员.所以是的,你可以Worksheet在所有情况下都使用界面,因为你不会丢失任何东西,并且可能需要它暴露的事件.

  • Jon Skeet*问*一个问题?我不得不采取这种罕见的机会作出回应!:) (4认同)