5

为什么.NET Standard 仍然有意义?

 3 years ago
source link: https://www.daqianduan.com/20197.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

.NET Standard 是.NET 官方的API规范,可在许多.NET环境中使用。之所以存在,面向.NET Standard 2.0的库提供了最大可能的覆盖范围,并启用了几乎所有现代的.NET功能,例如C#9,IAsyncEnumerable等,因此所有库都应针对该平台。

.NET标准背后的动机是在.NET生态系统中建立更大的一致性。

AJvEj2f.png!mobile

背景介绍

.NET Framework 很早并且没有跨平台,.NET Framework发行后,.NET的几种实现(例如 Mono 和 Unity) 出现在其他平台上,微软还发布了许多其他实现,例如 UWP, Silverlight和最新的.NET Core, Microsoft重命名为.NET 5的.NET Core是最重要的,因为它是Microsoft真正的.NET跨平台实现,并且Microsoft打算维护该平台。

Microsoft引入了可移植类库(PCL), 并最终引入了 .NET Standard,以便不同的实现可以共享一组通用的API,这意味着.NET代码在各个平台之间都是兼容的,并且您可以在任何实现中使用编译后的代码。根据Microsoft的说法,.NET Core,.NET 5,.NET Framework,Mono,Xamarin.iOS,Xamarin.Mac,Xamarin.Android,Universal Windows Platform和Unity都以某种方式支持.NET Standard。但是,.NET 5尚未运行所有这些平台。

将来,我们应该会看到.NET 5 正在支持更多的平台,因为Microsoft正在“积极开发”用于iOS和Android等平台的.NET(.NET 5+)。所以:.NET5 是具有统一功能和API的单一产品。

但是,目前,.NET Standard 是兼容大多数.NET 环境的唯一目标,如果要构建在所有这些平台上运行的库,则需要以.NET Standard 2.0为目标,这是实现的表格以及它们支持的.NET Standard版本

vYrAfeU.png!mobile

支持.NET Standard 2.0和.NET 5

您可以在.NET Standard 2.0中使用最新的.NET特性,比如 C#9,IAsyncEnumerable ,Span ,System.Text.Json等,这样的意义在于,这样做的好处是巨大的,在.NET Framework的项目上也可以使用这些功能。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
    <LangVersion>9</LangVersion>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0" />
    <PackageReference Include="System.Linq.Async" Version="5.0.0" />
    <PackageReference Include="System.Memory" Version="4.5.4" />
    <PackageReference Include="System.Text.Json" Version="5.0.0" />
  </ItemGroup>

</Project>

下边是这个库的一些代码,它同时支持了.NET Standard 2.0 和.NET 5,但是在一个 .NET Framework的运行项目上使用了这个库,.NET的新特性仍然可以使用。

using System;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;

namespace DotNetStandardLibrary
{
    public class ExampleClass
    {
        public string Test { get; }

        public ExampleClass(string test)
        {
            Test = test;
        }

        /// <summary>
        /// Uses the Span type
        /// </summary>
        public ExampleClass WriteSpans()
        {
            var spans = new Span<string>(new string[] { "One", "Two" });
            foreach (var span in spans)
            {
                Console.WriteLine(span);
            }

            return this;
        }

        /// <summary>
        /// Use an Async foreach with IAsyncEnumerable
        /// </summary>
        public static async Task DoAsyncNumbersAsync()
        {
            var asyncEnumerable = AsyncEnumerable.Range(0, 10);
            await foreach (var number in asyncEnumerable)
            {
                Console.WriteLine($"Awaited Number: {number}");
            }
        }

        /// <summary>
        /// Serialize and Deserialize with System.Text.Json
        /// </summary>
        public ExampleClass DoSerialize()
        {
            var dailyTemperature = new DailyTemperature(10, 20);
            var json = JsonSerializer.Serialize(dailyTemperature);
            dailyTemperature = JsonSerializer.Deserialize<DailyTemperature>(json);

            if (dailyTemperature == null)
            {
                throw new InvalidOperationException();
            }

            Console.WriteLine($"Json: {json}\r\nHigh: {dailyTemperature.HighTemp} Low: {dailyTemperature.LowTemp}");

            return this;
        }

    }

    public static class Extensions
    {
        /// <summary>
        /// C# Pattern matching example
        /// </summary>
        public static bool IsLetter(this char c) => c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z');
    }

    /// <summary>
    /// IAsyncDisposable Example
    /// </summary>
    public class AsyncDisposable : IAsyncDisposable
    {
        public ValueTask DisposeAsync() => new ValueTask(Task.FromResult(true));
    }

    /// <summary>
    /// Record example
    /// </summary>
    public record DailyTemperature(double HighTemp, double LowTemp);
}

在.NET Framework 是这样使用的

using DotNetStandardLibrary;
using System;
using System.Threading.Tasks;

namespace DotNet461ConsoleApp
{
    internal class Program
    {
        private static async Task Main()
        {
            var asyncDisposable = new AsyncDisposable();
            await asyncDisposable.DisposeAsync();

            _ = new ExampleClass("test").WriteSpans().DoSerialize();

            await ExampleClass.DoAsyncNumbersAsync();

            Console.WriteLine($"The character 7 {('7'.IsLetter() ? "is" : "is not")} a letter");
        }
    }
}

FRjUNnr.png!mobile

总结

.NET Standard可能会部分冗余,但.NET 5目前还不能替代.NET Standard, .NET 5提供了很多新特性,但是,像Unity和Mono这样的运行时仍然存在,并且在很多地方使用,他们可能会选择继续使用它们,而且,.NET Framework上仍然有成千上万的旧代码库,如果目标是.NET Standard 2.0,则保证这些代码库可以使用您的库, 所以.NET Standard还会存在一段时间,并且目前的范围最广。

原文作者: Christian Findlay

原文链接: https://christianfindlay.com/2020/12/21/net-standard/

最后

欢迎扫码关注我们的公众号 【全球技术精选】,专注国外优秀博客的翻译和开源项目分享,也可以添加QQ群 897216102

euyUZ3n.png!mobile

#感谢您访问本站#
#本文转载自互联网,若侵权,请联系删除,谢谢!657271#qq.com#

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK