.NET Standard 是.NET 官方的API规范,可在许多.NET环境中使用。之所以存在,面向.NET Standard 2.0的库提供了最大可能的覆盖范围,并启用了几乎所有现代的.NET功能,例如C#9,IAsyncEnumerable等,因此所有库都应针对该平台。
.NET标准背后的动机是在.NET生态系统中建立更大的一致性。
背景介绍
.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版本
支持.NET Standard 2.0和.NET 5
您可以在.NET Standard 2.0中使用最新的.NET特性,比如 C#9,IAsyncEnumerable
<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");
}
}
}
总结
.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
如何找到有意义的单词来表示从word2vec向量派生的每个k-means集群?
问答我使用Python中的gensim包加载预先训练的Google word2vec数据集.然后,我想使用k-means在我的单词向量上找到有意义的聚类,并找到每个聚类的代表性单词.我正在考虑使用其对应的 ... |
1 |
c# – 将超过96个.Net Standard 2程序集复制到Console(.Net framework)应用程序的bin文件夹中
问答在vs 2017.3预览版3中,我创建了一个包含三个项目的解决方案:Netstandard2库(.Net Standard v2.0预览版),控制台应用程序A(.Net框架)和控制台应用程序B(.Ne ... |
1 |
java – 通过改变每个迭代的每个字母将一个单词转换成另一个单词的算法,这个单词应该形成另一个有意义的单词?
问答我想制作一个将一个单词改为另一个单词的算法.例如,给定的单词是"MUD",我需要将其转换为"BED".对于每次迭代,我可以更改一个字符,但这应该形成另一个有意义 ... |
1 |
模型 – 视图 – 控制器 – MVC或MVP?哪种设计模式最有意义?
问答你们更喜欢哪个?我一直在研究两者,人们称之为肯定存在一些不一致的地方. 我会尝试记下差异是什么,如果我错了你可以纠正我. MVC >模型保存对它自己的观察者(视图)的引用,对模型的更新通知观察者 ... |
5 |
c# – 在库和.Net framework 4.6.1中使用.Net Standard 1.4和应用程序时,无法加载文件System.IO.FileSystem,Version = 4.0.1.0
问答我有一个包含库和2个应用程序的解决方案.这些应用程序代表相同的程序,其中一个程序是通过UAP10定位到Windows App Store,另一个是使用.Net Framework 4.6.1定位到Mi ... |
2 |
c# – 如何创建一个同时针对.NET 2.0和.NET Standard的库?
问答我有一个目前支持.NET 2.0的small library. 我不使用后来框架版本的任何功能,所以保持2.0支持会很好,但我也希望以.NET Core(或更确切地说,.NET标准)为目标. 我试图将 ... |
3 |
visual-studio-2017 – .NET Standard项目的代码覆盖率
问答如何获取使用Visual Studio 2017创建的.NET Standard项目的代码覆盖率结果? >我尝试使用Visual Studio附带的功能(菜单→测试→分析代码覆盖率→所有测试). ... |
2 |
Java中的闭包模拟是否有意义?
问答具有闭包的语言(例如Ruby)使得优雅的构造能够转换列表.假设我们有一个班级 class QueryTerm { String value; public String getValue() {... ... |
1 |
C 11原子:将它们与内存映射I / O一起使用是否有意义,甚至可能?
问答据我所知,C volatile和可选的内存asm for memory fence已用于在内存映射I / O之上实现设备驱动程序.在Linux内核中可以找到几个例子. 如果我们忘记未捕获的异常(如果有 ... |
1 |
`exit $?`与bash中的`exit`有意义不同?
问答我的理解是,在bash中,普通出口将完成一个脚本,其中包含最后一个命令的退出状态.但我也看到人们使用退出$?当我提出它具有相同的行为时被质疑. 这两个脚本之间有什么有意义的区别吗? #!/bin/ba ... |
1 |
c – 在可移动和不可复制的类上使用移动和交换习语是否有意义
问答如果我有一个类如 class Foo{ public: Foo(){...} Foo(Foo && rhs){...} operator=(Foo rhs){ swap(*this, ... |
3 |
android – AlertDialog.Builder类有什么意义?
问答在Android中,每个对话框都使用Builder显示该对话框类. Builder是这些类中的静态内部类.那么为什么Builder可以控制构建对话框呢?提前致谢.::它只是一个帮助类,它允许您调用链中 ... |
1 |
php – 在析构函数中归零私有变量有什么意义?
问答我在我正在使用的代码中发现了以下模式:在析构函数的某些类中,我发现私有变量是空的,例如: public function __destruct() { foreach($this->observ ... |
2 |
github-pages – 在GitHub页面中使用robots.txt有什么意义?
问答我知道robots.txt文件用于阻止第三方索引内容网站的网页爬虫. 但是,如果此文件的目标是划分站点的私有区域或保护私有区域,这是尝试使用robots.txt隐藏内容的意义,如果所有都可以在GitH ... |
2 |
c – 在动态内存上运行,重载const memeber函数是否有意义?
问答来自C Primer 5 Edition的练习使我陷入困境,这就像 Exercise 12.3: Does this class need const versions of push_back an ... |
1 |
有 #!在网址中组合有特殊意义吗?
问答我现在已经看到一些网址在网址中使用了这种符号组合:#! 例如:facebook: http://www.facebook.com/home.php?#!/?sk=messages 或推特: http: ... |
2 |
对象的监视器在java中的意义是什么?为什么要使用这个词?
问答当阅读关于java线程的文章时,我经常注意到以下表达式:"当前线程是此对象的监视器的所有者.我抓住的含义:线程获得对对象操作的权利.但我很困惑为什么使用短语"对象的监视器" ... |
2 |
sharepoint – 如何检查是否安装了MOSS Standard或MOSS Enterprise?
问答如何检查是否安装了MOSS Standard或MOSS Enterprise?::这个链接应该排除你- Determining sharepoint versions 编辑:文章现已消失,所以请看下面 ... |
1 |
active-directory – 在哪里可以找到LDAP Active Directory消息的列表,并有意义?
问答我收到错误: LDAPException: Invalid Credentials (49) Invalid Credentials LDAPException: Server Message: 80 ... |
2 |
c – 将所有内容放在QApplication的子类中是否有意义?
问答在我的基于插件的体系结构中,插件必须能够访问应用程序的所有核心组件,例如主窗口,settingswidget,设置,托盘图标和几个全局不可变变量. 由于应用程序是一个全局单例,因此可以直接将其子类化并 ... |
2 |