.NET 6+ 可以直接參照 .NET Framework 編譯的 DLL 嗎?
3 |
如果你是 .NET 開發者,考個簡單問題:
.NET 6+ 寫的程式可以直接參照引用 .NET Framework 編譯的 DLL 嗎?
(註:非 .NET Standard,純 .NET Framework 2.0/3.5/4.0/4.5 ~ 4.8,參考:淺談 .NET 類別程式庫跨平台開發)
我答錯了。
在我的印象中,.NET Framework 寫的專案必須轉成 .NET 6+ 或 .NET Standard 才能供 .NET 6+ (過去叫 .NET Core) 叫用。前幾天幫看問題,大驚! 事情怎麼跟我想得不一樣。如下圖範例,.NET 8 Console Application 居然直接參照 .NET Framework 4.8 寫的類別程式庫(實際案例是參照 .NET 2.0 跟 .NET 3.5 寫的程式庫),程式編譯成功,執行正常。
為此爬文,補齊一些知識。
相關文件在此 - .NET Framework 相容性模式。
.NET Standard 2.0 起加入了 .NET Framework 相容性模式,允許 .NET Standard 和 .NET Core 專案參考 .NET Framework 程式庫。但有個陷阱,並非所有專案都適用,如果 .NET Framework 程式庫用到 .NET 6+ 或 .NET Standard 不支援的 API,程式將會出錯,而且是編譯過程一片祥和,等執行階段再炸裂。
例如:我在 .NET 4.8 類別故意用了 .NET Core 不支援的另建 AppDomain、System.Web.Services.WebService (延伸閱讀:.NET 6+ 無法使用的 .NET Framework 技術)
using System;
namespace NetFXLib
{
public class Foo
{
public string SayHello()
=> "Hello from .NET Framework Class Library";
public string TestAppDomain()
=> AppDomain.CreateDomain("TestAppDomain").FriendlyName;
public string TestWebService()
{
var ws = new System.Web.Services.WebService();
return ws.GetType().FullName;
}
}
}
.NET 8 Console Program.cs 長這樣:
var foo = new NetFXLib.Foo();
TryRun(() => Console.WriteLine(foo.SayHello()));
TryRun(() => Console.WriteLine(foo.TestAppDomain()));
TryRun(() => Console.WriteLine(foo.TestWebService()));
void TryRun(Action action)
{
try
{
action.Invoke();
}
catch (Exception ex)
{
Console.WriteLine($"ERROR - {ex.Message}");
}
}
編譯沒問題,但執行時新增 AppDomain 及引用 System.Web.Services 相關型別的功能會出錯:
dotnet publish -r linux-x64 --no-self-contained
丟到 Linux 執行,結局相同:
相當然爾,若直接在 Linux 嘗試編譯,因 NetFXLib 是 .NET Framework 專案,是不可能成功的!
但若改成直接參照編譯好的 .NET Framework DLL,倒是可以成功編譯,但該出錯的還是要出錯。
由此可知,雖然 .NET 6+ 可以參照 .NET Framework DLL,但可能出現執行階段才冒出來的不相容錯誤,不能算是可靠的做法,等同失去 .NET 在編譯階段揪出錯誤的強型別優勢。故原則上還是建議將專案升級成 .NET 6+ 或 .NET Standard,會是較嚴謹可信賴的做法。
要將 .NET Framework 專案升級成 .NET 6+/.NET Standard 專案,微軟有個 .NET Upgrade Assistant 能協助升級,可多加利用。
A discussion on whether a .NET 6+ program can directly reference .NET Framework library.
Comments
# by Ho.Chun
.net standard 跟 .net framework / .net core 有什麼關係 ?
# by Jeffrey
to Ho.Chun, 文章開頭有篇 淺談 .NET 類別程式庫跨平台開發,裡面有較詳細的說明。
# by Dennis
好像.NET Framework 4.7~4.8 我在Linux上可以用得到,把TTF字型放上去產製PDF也可以讀取。