2012-06-14 65 views
9

針對2.0,3.0,3.5,4.0和4.5的單個.NET程序集如何同時支持C#和VB.NET使用者的擴展方法?在.NET 2.0中使用擴展屬性的Escape Catch-22

標準的建議是補充一點:

namespace System.Runtime.CompilerServices 
{ 
    public sealed class ExtensionAttribute : Attribute { } 
} 

這種做法通過moreone Microsoft employee建議,並甚至在MSDN magazine特色。它的widelymany bloggers稱爲「沒有不良影響」。

哦,除了它會導致從.NET.NET 3.5或更高版本的VB.NET項目編譯器錯誤。

Microsoft.Core.Scripting.dll figured it out的作者,並改變「公」到「內部」。

namespace System.Runtime.CompilerServices 
{ 
    internal sealed class ExtensionAttribute : Attribute { } 
} 

這似乎解決了VB兼容性問題。

所以我滿懷信心地使用這種方法爲widely-used ImageResizing.Net library的最新版本(3.2.1)。

但是然後,我們開始針對某些針對.NET 3.5+的用戶或多或少地隨機獲取此編譯器錯誤(original report)。

Error 5 Missing compiler required member 
'System.Runtime.CompilerServices.ExtensionAttribute..ctor' 

由於的MSBuild /編譯VisualStudio中顯然不懶得看作用域規則解決命名衝突時,和裝配引用的順序播放一個不很-docuemented角色,我不完全理解爲什麼當發生這種情況。

有一個few hacky workarounds,如更改程序集名稱空間,重新創建項目文件,刪除/讀取System.Core和擺弄目標版本的.NET框架。不幸的是,這些解決方法中沒有一個是100%(除了別名,但這是一個令人無法接受的痛苦)。

如何解決這一點的同時

  1. 維持所述組件內擴展方法使用支持,
  2. 用於.NET 2.0/3.0
  3. 不需要爲每個.NET框架版本的多個組件維護支持。

或者,是否有一個修復程序,使編譯器注意範圍規則?

上,這樣纔不會回答這個問題

+0

呃。你的賞金缺少零。最好與微軟支持部門合作,儘管他們可能會用'不支持'來解僱它。 –

回答

1

我們遇到了與IronPython相同的問題。 http://devhawk.net/2008/10/21/the-fifth-assembly/

我們最終將自定義版本的ExtensionAttribute移動到了它自己的程序集中。這樣,客戶可以選擇引用我們自定義的ExtensionAttribute程序集或System.Core - 但從來都不是!

另一個棘手的問題是,您必須始終部署ExtensionAttribute程序集 - 即使您沒有在項目中引用它。您公開擴展方法的項目程序集將有一個用於該定製ExtensionAttribute程序集的assemblyref,因此如果無法找到,CLR將會不高興。

鑑於.NET 2.0支持的強硬要求,我認爲最好的辦法就是根本不使用擴展方法。我不熟悉ImageResizer項目,但它聽起來像是ImageResizer中的最近更改。將擴展方法改爲傳統的靜態方法有多大的可行性?我們實際上已經考慮過IronPython/DLR,但它不可行(我們在那時與LINQ合併,而LINQ在本質上完全使用了擴展方法)。

+0

感謝您使用鏈接更新文章!我認爲Newtonsoft.Json遇到了同樣的噩夢......太多的博客表示沒有影響,當我讀到六個博客上無可爭議的同一事實時,我認爲這是真的! –

+0

只是想法,我們可以解決類型轉發嗎? –

+0

我們仍然需要該程序集的多個版本... –