5

我正在使用 VS 2010 并将我们的应用程序升级到 .NET 4。该应用程序以 Excel 为基础构建,我们希望利用 .NET 的一些改进来使用 Excel。但是我遇到了一个奇怪的错误,这似乎是由在通用字典中使用 Excel 互操作对象引起的。这是生成的错误:

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,但这似乎并没有改变任何东西。请让我知道是否有任何解决方法。

4

3 回答 3

11

Adrian 给出了几乎正确的答案,但有更好的方法来处理这个错误。不要关闭 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 Type.IsEquivalentTo

typeOfWorkbookFromA.IsEquivalentTo(typeOfWorkbookFromB) == true
  1. 在等效接口上参数化的相同泛型类的两个实例不被认为是等效的。

希望这可以帮助。

于 2012-02-16T08:46:14.277 回答
4

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

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

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

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

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

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

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

于 2009-12-01T14:14:54.287 回答
2

我遇到了 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; }
于 2015-09-08T09:20:56.760 回答