2009-11-19 55 views
4

我正在VS 2010中工作,并将我们的应用程序升级到.NET 4.应用程序是以Excel为基础构建的,我们希望利用.NET对于使用Excel的一些改进。但是我遇到了一个奇怪的错误,这似乎是由通用字典中使用Excel Interop对象造成的。这里是产生差错:我们无法在.NET 4.0中的泛型对象中使用Interop对象吗?

C:\MyApp\TheAssembly\MyClass.cs(823,57): 
error CS1769: Type 'MyApp\OtherAssemply.IMyController.SheetReports' from assembly 'c:\MyApp\OtherAssemply.\bin\Debug\OtherAssembly.dll' 
cannot be used across assembly boundaries because it has a generic type 
parameter that is an embedded interop type. 

下面是有问题的实际属性:

Dictionary<Excel.Worksheet, IReportSheet> SheetReports { get;} 

难道我们不能在通用对象使用互操作的对象?如果是这样,这是.NET 4.0中的一个严重限制。我尝试将Embed Interop属性设置为false,但这似乎没有改变任何内容。请让我知道是否有这个问题。

干杯!

埃里克

回答

3

VS2010的一个新特性是嵌入互操作类型到组件,而不是使用外部互操作程序集。

好处是您不需要分发互操作程序集。

缺点是每个程序集都有自己的一组interop类型。

由于类型“Excel.Worksheet”现在是内部的组件,其它组件不能使用基于它的通用型(这是错误消息所说的话)

你得到一个类似的错误,如果你做

internal class X { } 
public class Y { 
    public List<X> l; 
} 

我没有使用VS2010,但我敢肯定,必须有一个选项,其中的某处,你可以关闭嵌入的互操作类型。

+0

阿德里安, 这就是我想通了,所以感谢您的确认。我最终不得不在整个解决方案中关闭嵌入。我正在研究一些方法,但没有时间去尝试。也许某种界面?让我知道你的想法。 谢谢! – Erick 2009-12-01 17:35:38

+0

我能想到的唯一方法就是创建某种装配关联(如STA线程模型)。你可以通过将它们作为对象转换来传递互操作对象,但只要你需要访问它们,你就必须从创建它们的程序集中调用它。另一方面,在办公室使用互操作程序集有什么不对?无论如何,它们将在用户机器上,因为它们是正常安装的一部分。你不会从嵌入式互操作中获得任何东西。 – adrianm 2009-12-02 07:23:58

+0

正确。嵌入并不是那么美妙。为了使用互联网,用户必须拥有Office的许可副本。大多数将有PIA预先安装的Office 2007 ...:D – 2010-02-25 04:48:51

9

阿德里安给出了几乎正确的答案,但有一个更好的方法来处理这个错误。请勿关闭Embed Interop Types,而应使用通用接口:

IDictionary<Excel.Worksheet, IReportSheet> SheetReports { get;} 

CLR 4.0引入了类型等同的概念。如果我们略微简化这意味着什么,那么我们可以说CLR 4.0将两个相同名称的接口类型对待,它们具有相同的Guid属性,就好像它是相同类型一样。注意到类型等价性是非常深入地构建到系统中的,并且使得对等类型的工作就像是一种类型一样。几个例子; 1.您可以使用反射来调用实现等效接口的对象的接口方法。 2.在等同接口上参数化的通用接口的实例也被认为是等效的。

C#和VB编译器利用此功能来实现“嵌入互操作类型”功能。

我们的例外: 1.相当于接口的System.Type的之间的参考比较,因为这些失败仍然是两个不同类型的类型系统:

typeOfWorkbookFromAssemblyA.Equals(typeOfWorkbookFromAssemblyB) == false 

但有一个新的API类型。IsEquivalentTo相同的通用类等效接口参数的

typeOfWorkbookFromA.IsEquivalentTo(typeOfWorkbookFromB) == true 
  1. 两种情况不被认为是等同的。

希望这会有所帮助。

+0

感谢一堆这个建议,它的工作!我给你一个! – Pascal 2014-10-29 16:14:42

1

我进入了类似的问题与Outlook AddIn和由Misha提供的答案就像一个魅力。 我有一个属性

public List<Microsoft.Office.Interop.Outlook.Attachment> Attachments { get; set; } 

List简单的改变接口01​​解决了这个问题

public IList<Microsoft.Office.Interop.Outlook.Attachment> Attachments { get; set; } 
相关问题