dotnet core TargetFramework 決議順序測驗
Intro
現在 dotnet 的 TargetFramework 越來越多,拋開 .NET Framework 不談,如果一個類別庫支持多個 TargetFramework 應用實際運行的時候會使用哪個版本的 API 呢,之前一直都是想當然的自以為是了,于是想測驗一下實際決議是怎么樣的,來看下面的示例吧
Sample
Library Sample
首先來看類別庫示例專案:
專案檔案如下:
類別庫提供了多個 TargetFramework 的支持:
netstandard2.0netcoreapp2.1netstandard2.1netcoreapp3.1net5.0net6.0
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netcoreapp2.1;netstandard2.1;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
</PropertyGroup>
</Project>
類別庫里只提供了一個類,只有一個用于測驗的方法,方法實作如下:
public class Test
{
public static string GetResult()
{
var result = string.Empty;
#if NET6_0
result = "NET6.0";
#elif NET5_0
result = "NET5.0";
#elif NETCOREAPP3_1
result = "NETCOREAPP3_1";
#elif NETCOREAPP3_0
result = "NETCOREAPP3_0";
#elif NETCOREAPP2_1
result = "NETCOREAPP2_1";
#elif NETSTANDARD2_1
result = "NETSTANDARD2_1";
#elif NETSTANDARD2_0
result = "NETSTANDARD2_0";
#endif
return result;
}
}
通過條件編譯在不同的 TargetFramework 下回傳不同的值以測驗實際執行的代碼
Executable Sample
接著看一個可執行的 Console 應用,專案檔案示例如下:
Console 應用支持的 TargetFramework 如下:
- netcoreapp2.0
- netcoreapp2.1
- netcoreapp3.0
- netcoreapp3.1
- net5.0
- net6.0
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.0;netcoreapp2.1;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
<NoWarn>;NETSDK1138</NoWarn>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\TestClassLibrary\TestClassLibrary.csproj" />
</ItemGroup>
</Project>
因為 netcoreapp2.0 和 .netcoreapp3.0 已經不再支持,如果直接使用會得到一個 Warning:

所以在專案檔案中配置了 <NoWarn>;NETSDK1138</NoWarn> 來忽略這個警告
測驗代碼很簡單,直接呼叫類別庫示例中的測驗方法:
Console.WriteLine(Test.GetResult());
Console.WriteLine("Hello World!");
Console.ReadLine();
Test Output
接著我們就來測驗吧,先思考一下吧,不同的 TargetFramework 輸出的結果分別是什么呢?
net6.0

net5.0

netcoreapp3.1

netcoreapp3.0

netcoreapp2.1

netcoreapp2.0

More
從上面的測驗結果其實就能夠大概看出來,多個 TargetFramework 的決議順序,可執行應用程式首先會匹配與當前運行的 TargetFramework 相符的框架,如果沒有與當前運行的 TargetFramework 相符的框架,則會fallback 到低版本的 .NET 框架上,優先選擇高版本的框架,如果當前運行的框架版本是 net6.0,但是類別庫不支持 net6.0,則會使用 net5.0,如果類別庫不支持 net5.0 則會使用 netcoreapp3.1以此類推,
如果既有 .NET Core 的框架支持又有 .NET Standard 的支持,則會優先使用 .NET Core 框架,沒有可用的 .NET Core 框架的話再開始看類別庫支持的 .NET Standard 的支持,優先選擇當前框架支持的高版本的 .NET Standard 框架
最后擴展一下,參考單個類別庫是上面這樣的,如果類別庫參考了類別庫,那又會如何呢
測驗專案結構如下,測驗專案基于 .NET6.0,參考了一個基于 netstandard2.0/netstandard2.1 的類別庫專案 ClassLibrary1,而 ClassLibrary1 參考了另外一個基于netstandard2.0/netstandard2.1/netcoreapp2.1的類別庫專案,測驗方法和上面的差不多,測驗專案呼叫 ClassLibrary1 中的測驗方法(實際呼叫了 ClassLibrary2 中的測驗方法)
ConsoleApp(NET6.0)
- ClassLibrary1(
netstandard2.0/netstandard2.1)- ClassLibrary2(
netstandard2.0/netstandard2.1/netcoreapp2.1)
- ClassLibrary2(
輸出結果如下:

從上面的結果來看,實際的決議結果運行結果都是根據最終執行到的類別庫結合應用當前運行框架來決定使用哪個版本的代碼的
References
- https://github.com/WeihanLi/SamplesInPractice/tree/master/UnexpectedSamples
- https://docs.microsoft.com/en-us/dotnet/core/tutorials/libraries#how-to-target-the-net-framework
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/262333.html
標籤:.NET技术
上一篇:WPF之屬性
