2016-02-12 70 views
7

請注意,此可能this question的重複,我不完全確定。代碼合同重寫失敗,'無法解析成員參考'

我的問題是,我有一個類庫項目有一個第三方類型庫(COM)的引用。我想提出的合同到方法的類庫,像這樣:

public class foo 
{ 
    public static int divide(TypeFromTypeLib tftl, int a, int b) 
    { 
     Contract.Requires<ArgumentException>(b != 0); 
     return a/b; 
    } 
} 

,然後有一個客戶端項目利用這種方法,例如中

var n = foo.divide(null, 4, 2); 

但我也想客戶端項目也使用它的一些方法中的合同。因此,我將兩個項目的代碼合同屬性都設置爲'執行運行時合同檢查'(沒有這些代碼,運行時斷言會告訴您它需要此設置)。

現在,當我再嘗試編譯客戶端,我得到以下錯誤:

Could not resolve member reference: my_class_lib.foo::divide.

ccrewrite : error : Rewrite aborted due to metadata errors.

這似乎不可避免的 - 一個方法被調用任何時候它有來自第三方類型庫的類型發生這種情況。從方法的簽名中刪除類型,這很好。

任何人都可以解釋爲什麼發生這種情況?這是我的代碼結構是否存在根本性缺陷(如果是這樣,爲什麼?),還是代碼契約的怪癖? 是否有針對此問題的建議修復?

+0

我從ccrewrite中得到這個錯誤,這是從第一方庫中的方法在簽名中嵌入了互操作類型。 – JamesFaix

+0

我讓我的項目在VS2015中打開並切換到VS2013,問題就消失了。 Roslyn編譯器似乎以不同於舊編譯器的方式處理嵌入式interop類型,但我找不到任何有關它的文檔或對話。可能相關:http://stackoverflow.com/questions/35641972/why-does-visual-studio-2015-throw-more-cs1769-compiler-errors-than-vs2013 – JamesFaix

+0

你安裝了什麼版本的代碼合同?直到2016年1月26日發佈v.10.10.10126.2-rc1爲止,我從未在運行Visual Studio 2015的代碼合同中獲得運行時檢查。此版本是第一個主要的社區驅動的代碼合同發佈版本,未決問題。它可以從https://github.com/Microsoft/CodeContracts/releases下載。我已經安裝了它,運行時檢查現在再次適用於我。 –

回答

2

說實話,我不知道爲什麼ccrewrite與互操作類型的問題,但我可以給你3個解決方法:

解決方案1 ​​

這一個是最簡單的:

  • 轉至項目參考文獻列表。
  • 查找第三方類型庫。
  • 右鍵單擊。
  • 從上下文菜單中選擇屬性
  • 更改將互操作類型從True更改爲False。

您必須爲兩個項目都這樣做。這個解決方案的缺點是在構建之後,您將在bin文件夾中獲得額外的互操作程序集。

解決方案2

另一種解決方案可能是來自第三方的類型庫,從一個公共接口即刪除類型:

public class foo 
{ 
    public static int divide(int a, int b) 
    { 
     return divide(null, a, b); 
    } 

    private static int divide(TypeFromTypeLib tftl, int a, int b) 
    { 
     Contract.Requires<ArgumentException>(b != 0); 
     return a/b; 
    } 
} 

當然你也可以做,只有當你不需要在您的客戶端使用TypeFromTypeLib

解決方案3

如果您需要使用您的客戶端TypeFromTypeLib,你可以寫一個包裝該類即:

public class MyTypeFromTypeLib 
{ 
    //... 
} 

public class foo 
{ 
    public static int divide(MyTypeFromTypeLib mytftl, int a, int b) 
    { 
     var tftl = new TypeFromTypeLib(); 
     //Map MyTypeFromTypeLib to TypeFromTypeLib 
     //... 
     return divide(tftl , a, b); 
    } 

    private static int divide(TypeFromTypeLib tftl, int a, int b) 
    { 
     Contract.Requires<ArgumentException>(b != 0); 
     return a/b; 
    } 
} 

然而,這種解決方案很麻煩,因爲需要額外的課程。

相關問題