Excel 我们是否无法在.NET 4.0中的通用对象中使用互操作对象?

Excel 我们是否无法在.NET 4.0中的通用对象中使用互操作对象?,excel,.net-4.0,excel-interop,Excel,.net 4.0,Excel Interop,我正在VS2010中工作,正在将我们的应用程序升级到.NET4。该应用程序是以Excel为基础构建的,我们希望利用.NET的一些改进来使用Excel。但我遇到了一个奇怪的错误,这似乎是由于在通用字典中使用Excel互操作对象引起的。以下是生成的错误: C:\MyApp\TheAssembly\MyClass.cs(823,57): error CS1769: Type 'MyApp\OtherAssemply.IMyController.SheetReports' from assembly

我正在VS2010中工作,正在将我们的应用程序升级到.NET4。该应用程序是以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;}
Dictionary SheetReports{get;}

我们是否无法在通用对象中使用互操作对象?如果是这样,这是.NET4.0中的一个严重限制。我尝试将嵌入互操作属性设置为false,但这似乎没有改变任何事情。请告诉我是否有办法解决此问题。

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

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

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

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

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

internal class X { }
public class Y {
    public List<X> l;
}
内部类X{}
公共Y类{
公开名单l;
}

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

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

IDictionary<Excel.Worksheet, IReportSheet> SheetReports { get;} 
但是有一种新的API类型。ISEquivalento

typeOfWorkbookFromA.IsEquivalentTo(typeOfWorkbookFromB) == true
  • 在等效接口上参数化的相同泛型类的两个实例不被视为等效
    希望这能有所帮助。

    我在Outlook AddIn上也遇到了类似的问题,Misha提供的答案很有魅力。 我有一笔财产

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

    阿德里安,我就是这么想的,谢谢你的确认。我最终不得不在整个解决方案中关闭嵌入。我正在寻找一些解决方法,但还没有时间去试验。也许是某种接口?让我知道你对此的想法。谢谢我能想到的唯一其他解决方法是创建某种程序集关联(如STA线程模型)。可以通过将互操作对象强制转换为对象来传递互操作对象,但一旦需要访问它们,就必须从创建它们的程序集进行调用。另一方面,在office中使用互操作程序集有什么问题?因为它们是正常安装的一部分,所以它们无论如何都会在用户计算机上。您将不会从嵌入式互操作中获得任何东西。正确。嵌入并不是那么美妙。为了使用interops,用户必须拥有Office的许可副本。大多数将配备Office 2007,其中预装了PIA的……:D
    public List<Microsoft.Office.Interop.Outlook.Attachment> Attachments { get; set; }
    
    public IList<Microsoft.Office.Interop.Outlook.Attachment> Attachments { get; set; }