• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

dotnet core TargetFramework 解析顺序探索

C# WeihanLi 3031次浏览 0个评论

dotnet core TargetFramework 解析顺序测试

Intro

现在 dotnet 的 TargetFramework 越来越多,抛开 .NET Framework 不谈,如果一个类库支持多个 TargetFramework 应用实际运行的时候会使用哪个版本的 API 呢,之前一直都是想当然的自以为是了,于是想测试一下实际解析是怎么样的,来看下面的示例吧

Sample

Library Sample

首先来看类库示例项目:

项目文件如下:

类库提供了多个 TargetFramework 的支持:

  • netstandard2.0
  • netcoreapp2.1
  • netstandard2.1
  • netcoreapp3.1
  • net5.0
  • net6.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:

dotnet core TargetFramework 解析顺序探索

所以在项目文件中配置了 <NoWarn>;NETSDK1138</NoWarn> 来忽略这个警告

测试代码很简单,直接调用类库示例中的测试方法:

Console.WriteLine(Test.GetResult());

Console.WriteLine("Hello World!");
Console.ReadLine();

Test Output

接着我们就来测试吧,先思考一下吧,不同的 TargetFramework 输出的结果分别是什么呢?

net6.0

dotnet core TargetFramework 解析顺序探索

net5.0

dotnet core TargetFramework 解析顺序探索

netcoreapp3.1

dotnet core TargetFramework 解析顺序探索

netcoreapp3.0

dotnet core TargetFramework 解析顺序探索

netcoreapp2.1

dotnet core TargetFramework 解析顺序探索

netcoreapp2.0

dotnet core TargetFramework 解析顺序探索

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)

输出结果如下:

dotnet core TargetFramework 解析顺序探索

从上面的结果来看,实际的解析结果运行结果都是根据最终执行到的类库结合应用当前运行框架来决定使用哪个版本的代码的

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


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明dotnet core TargetFramework 解析顺序探索
喜欢 (0)

您必须 登录 才能发表评论!

加载中……