我们无法在.NET 4.0中的通用对象中使用Interop对象吗?

时间:2009-11-19 18:54:34

标签: excel .net-4.0 excel-interop

我正在使用VS 2010并致力于将我们的应用程序升级到.NET 4.该应用程序是以Excel为基础构建的,我们希望利用.NET的一些改进来使用Excel。但是我遇到了一个奇怪的错误,这个错误似乎是在通用字典中使用Excel 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;}

我们是否无法在通用对象中使用Interop对象?如果是这样,这是.NET 4.0中的严重限制。我尝试将Embed Interop属性设置为false,但这似乎没有改变任何东西。如果有任何解决方法,请告诉我。

3 个答案:

答案 0 :(得分:9)

Adrian给出了几乎正确的答案,但有更好的方法来处理这个错误。不要关闭嵌入互操作类型,而是使用通用接口:

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 Type.IsEquivalentTo

typeOfWorkbookFromA.IsEquivalentTo(typeOfWorkbookFromB) == true
  1. 在等效接口上参数化的两个相同通用的实例不被视为等效。
  2. 希望这有帮助。

答案 1 :(得分:3)

VS2010的一个新功能是将互操作类型嵌入到程序集中,而不是使用外部互操作程序集。

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

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

由于“Excel.Worksheet”类型现在是程序集的内部类型,因此其他程序集不能使用基于它的泛型类型(这是错误消息所说的)

如果你这样做,你会得到类似的错误

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

我没有使用过VS2010,但我确信必须有一个可以关闭嵌入式互操作类型的选项。

答案 2 :(得分:1)

我遇到了与Outlook AddIn类似的问题,Misha提供的答案就像一个魅力。 我有一个房产

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

简单地将List更改为接口IList解决了问题

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