2009-11-19 59 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; } 
相關問題