.Net Core、Portable、Standard、Compact、UWP 和 PCL 之间的区别?

Posted

技术标签:

【中文标题】.Net Core、Portable、Standard、Compact、UWP 和 PCL 之间的区别?【英文标题】:Difference between .Net Core, Portable, Standard, Compact, UWP, and PCL? 【发布时间】:2017-03-23 17:03:12 【问题描述】:

听说过

.Net Core .Net 便携版 .Net 标准 .Net 精简版 通用 Windows 平台 可移植类库

所有这些都向我解释为“允许您针对多个平台的完整 .Net 的子集”。所以我的问题是

    有什么区别!? 如果我想编写一个可供尽可能多的受众使用的库,我需要使用其中的哪一个(或多个)

(我的具体情况:我有a library,它针对.Net 2.0、.Net 4.5 和UWP。针对UWP 需要创建一个新的VS 项目并链接所有现有文件,这是一个巨大的痛苦。现在有人告诉我它不适用于 PCL,从它的声音来看,我必须为 .Net Standard 再次这样做!?)

【问题讨论】:

@downvoter:为什么要投反对票?我的问题不是很清楚吗?我试图研究但没有发现任何解释,只有更多的混乱(例如this图像暗示.Net核心库与.Net基类库分开,但this图像暗示它们都是共享) 有详细讨论here @PeterTorr-MSFT:我已经读过,这是导致这个问题的部分原因。它没有回答为什么 .Net Framework 和 .Net Core 被认为是不同的东西,或者它们有何不同。它没有回答 .Net Standard 兼容的 .Net Framework/Core 版本。它没有说明其他“完整框架的子集”如何适应,也没有告诉我需要针对哪些框架来支持每个人。 你忘记了 .NET Micro。我的意思是,不再有太多人关心它了,但只要我们的目标是完整性并提及 Compact... 更令人困惑的是,几乎没有文章似乎对 platform(UWP、Mono、CLR、.Net Core、.NET Native 和各种 Phone/嵌入式风格)、构建技术(MSBuild、.NET Core、.NET Native)和运行时库集(BCL、Silverlight、UWP、.NET Core、.NET Native) .并非所有组合都存在。 .NET Standard 是通过库进行标准化的尝试,但故意将平台和构建技术留给您,让您从其他方面解开。随着 .NET Core 的成熟和吞噬其他核心,这应该会变得不那么令人困惑,但那还有一段路要走。 【参考方案1】:

与 cmets 中的链接一样,already a description by Microsoft 概述了所有这些信息。但是,从您的回答看来,您似乎并没有完全理解整个事情。它非常很长,所以这里(希望)是一个 tl;dr 版本。

我们将从上面链接中的下表开始,希望这能消除一些困惑:

对后来发现这一点的其他人的简要概述:.NET 库在其存在的 15 年中经历了很多的更改和移植。在那个时候,许多智能手机现在的功能几乎与 2001 年使用的某些台式机一样强大。在那期间,subsets of the .NET framework were created (and quickly abandoned) 可用于不同的平台。随着 Satya Nadella 的新方法使 .NET 成为尽可能广泛的平台,事情需要改变。

作为一项已有 15 年历史的技术,需要改进。 .NET Core 自 2014 年以来一直作为 .NET 架构的彻底改革而工作。它已从头开始重写为 .NET 语言的新版本。 Core 的目标之一是支持跨平台部署。无论是在 iPhone/android/XBox One 上运行的应用程序,还是可以托管在 IIS 或 Linux 机器上的网站,.NET Core 都能满足您的需求。它通过几种不同的方式实现这一点,包括不需要在计算机上安装 .NET Framework,而是将必要的库与您的解决方案打包在一起。

.NET Core 最引人注目的是 ASP.NET 的巨大变化。旧的 System.Web 完全消失并改写为as performant as possible with impressive results。单独的 WebApi 控制器消失了,因为一切都在单个控制器中完成。整个过程现在是选择加入,而不是默认允许您可能不希望的事情。

但是,作为开发人员,我们最终会希望迁移一些应用程序,那么我们如何确保我们已经编写的代码没有对方法进行一些小的名称更改,从而破坏了巨型解决方案的编译? .NET Standard 出现了。这是一组必须实现的 API,您的平台才能自称为“.NET”。

由于我们多年来一直使用的基本 .NET Framework 已经很成熟,它被用作标准所包含内容的基础。然而,一切都没有包括在内,那有什么意义呢?因此,标准只是各种类型的 .NET 平台之间存在的通用 API。 您最终不会在“.NET Standard”中编写代码。

Xamarin(包含在上表中)在 2016 年为 purchased by Microsoft,该技术用于帮助构建(或至少激发)跨平台的 .NET Core。它仍然作为一种工具存在,但与过去使用的方式相同。根据表格,它将在 vNext 版本中与 .NET Standard 2.0 兼容。但是,它的目标受众不会改变。

要直接回答您的问题,如果您想使用尽可能广泛的单一部署解决方案编写应用程序,您可能需要使用 .NET Core。但是,如果您使用的是当前基于 .NET Framework 2.0 和 4.5 构建的库,那么您将无法使用 .NET Framework 并拥有单独的 UWP 解决方案为那个目标。

如果它提供了可以通过 Web API 调用进行调用的功能,那么您可以在 .NET Framework 中的服务器上运行该功能,并在 .NET Core 中使用单一解决方案部署给最终用户。如果它已集成到您的代码中,那么在提供 .NET Core 更新之前,您会很不幸。

希望这已经消除了不同技术名称之间的一些混淆。

编辑

在对您的具体情况进行了一些澄清后,我可以为您澄清一下。您可以制作一个同时针对 .NET Framework 和 .NET Core 的解决方案。以完全不同的方式进行编译,使用不同的底层技术,因此这与尝试在 .NET 2.0 解决方案中使用 .NET 4.5 版本的情况相同。

但是,有tutorials 允许您将项目移植到Core。在大多数情况下,只需将类主体复制到您的 .NET Core 解决方案中,大多数东西都会正常工作。有些部分已被放弃,有些部分尚未完全 100% 充实(不适合您的情况,但 Entity Framework 不具有所有相同的功能)。也有一些调用发生了一些变化。

好消息是,向前发展,.NET Core 将为您提供尽可能广泛的覆盖范围。 .NET Framework 不会消失,但它和 Core 将更加同步。

.NET Core 的另一个好处是它使用迭代方法进行部署,因此您不必等待 2 年才能进行下一次重大升级。通过 NuGet 交付所有内容,您可以更快地完成改进和新功能。

【讨论】:

就我而言,我没有使用任何第三方库,但我确实希望我的库在旧的 .Net 2.0 项目和新项目中都是可定位的。 .Net Core 就足够了吗?或者我是否需要一个针对 .Net 2.0 和 .Net 4.5 的项目,以及针对 UWP 和 .Net Core 的单独项目? PCL 也适用于哪里——我的库可以被 PCL 项目使用吗? (显然目前不是,尽管针对 .Net 2.0、4.5 和 UWP) @BlueRaja-DannyPflughoeft:您的库是否有任何条件代码使其在 .NET 4.5 上执行某些在 .NET 2.0 上不执行的操作?如果没有,那么您可以将 .NET 4.5 从您需要关心的平台选择列表中剔除,因为任何 .NET 2.0 库都可以在 .NET 4.5 上正常工作,而无需进行二进制更改。 (除了一些小的改动,如果它们对你很重要,那么它们已经被条件代码覆盖了。) @JeroenMostert yes “要直接回答您的问题,如果您想使用尽可能广泛的单一部署解决方案编写应用程序,您会希望使用 .NET Core”。我的印象是 .NET Core 是所有 .NET 版本中最常见的分母。然而,情况似乎并非如此。 IE。没有可用于当前所有现有.NET 平台的功能“核心”,我无法创建一个库“来统治所有平台”,对吗?例如,我必须在除 UWP 之外的任何地方使用 Socket,并在 UWP 版本中使用 StreamSocket。 @Alex 不幸的是,没有办法编写一个可以被所有类型的框架使用的库,除非你想用 IL 来编写它。【参考方案2】:

我假设您已经阅读了带有漂亮桌子的 Microsoft 文章,现在一切都一清二楚了。如果是这样,那么在我花了一个下午的大部分时间研究这个之前,你和我在同一条船上(并试图将我的反射密集型库移植到 .NET Core,我应该提到这也是我的 .NET Core 移植工作)。以下不是官方的派对路线,而是我通过大量阅读(以及自 .NET 1.0 以来成为 .NET 开发人员)所发现的内容的个人总结。我不能保证它的完全准确性(尤其是在移动开发方面,我几乎完全不知道),当然欢迎更正。如果有很多,我会做维基。

我将或多或少地按时间顺序进行介绍,因为我发现如果您想了解新旧之间的关系,这才是最有意义的。它可能应该减少很多,但目前我没有时间这样做。不过,一个 TL;DR 版本在最后。

漫长而曲折的路

尽管有 Java 血统,.NET 从未认真尝试过“一次编写,随处运行”。它最初是在 Windows 阵营中开始的,尽管它编译为字节码并且没有过度使用显式的 Windows 主义,因此理论上非常便携,但这并不是 MS 真正感兴趣的。 .NET Framework 的一部分很早就是开源的,一群开源爱好者选择并使用它,为我们提供了 Mono。 Mono 很重要,因为它是 .NET 的第一个备用平台库集,并说明了平台、库和工具链的概念。 Mono 尝试提供(或多或少)公共语言运行时及其相关基类库的完整实现。这很重要:尽管 Mono 在 Linux(和其他一些 Unices)上运行,但它不是一个单独的平台,因为它实现了(某些版本的)CLR + BCL。对于应用程序开发人员来说,存在运行时差异(路径名等),但对于实际的库编程,您可以考虑 Mono 和 .NET Framework for Windows“相同”平台,但实现略有不同。我强调这一点是因为我们将遇到针对 Windows 的 .NET 代码,这些代码在 CLR 上运行,并且(具有讽刺意味或其他方面)更难移植。

然后出现了 Windows Phone(多个版本)、Windows CE(多个版本)、Windows Embedded CE、Windows Toaster(好吧,那并不真正存在)和一些 .NET 风格基本上每次都被重新发明——仍然是 .NET,但运行时和/或 BCL 的基本内容丢失或更改。这是我们获得 .NET Compact.NET MicroWindows Phone(旧风格,没有单独的框架名称)和 的地方银光。所有这些都应该被视为独立的平台 + 库组合,它们与 .NET 框架非常相似,足以使跨平台开发成为可能,但与它的差异又足以使其没那么容易。为了跟踪对共享库来说最不方便的地方支持什么,有人提出了可移植类库及其相关配置文件(其集合被称为 .NET便携式参考组件)。

基本上,您以 .NET 版本、平台(和库)的一组特定组合为目标,并且您将获得模仿这些组合进行编译的参考程序集。根据您明确希望定位的口味,存在许多不同的配置文件。这是 .NET Standard 现在大规模尝试的第一次尝试。基本上,PCL 现在已经过时,除非您的目标是 .NET Standard 不支持的东西。 .NET Standard 摒弃了使用大量不同配置文件的想法,这很好,但代价是削减了您的库可能更早针对的一些内容,这很糟糕。有在线资源可帮助您从 PCL 过渡到 .NET Standard。如果您现在正在研究可移植代码,那么您不想专注于 PCL,除非您真的想支持一些非常边缘的平台(无意冒犯仍在为它们开发的人)。 p>

通用 Windows 平台,顾名思义,是一个平台。具体来说,它是 Windows 应用商店应用程序(在桌面和手机上)支持的 .NET 平台。就是这样,不多也不少。最好将其视为 Silverlight 的自然继承者,因为它是对桌面和移动设备的沙盒框架支持。尽管名称如此,但它不是一个通用 平台,也不是您希望所有代码的目标。它是您可能希望为您的代码启用的平台,它的独特之处在于它是我所知道的唯一一个在同一版本中有两个运行时的平台。马上来!

.NET Native 在原帖中没有提到,但在这些讨论中经常出现,因为它也是新的,就像 .NET Core 一样,而且听起来很性感,因为它直接编译 .NET到机器代码(提前编译,而不是 JIT 编译)。在发布模式下编译时,它不是一个完整的新平台,而是 UWP 应用程序(并且仅限于那些)的新运行时。在调试模式下,它们使用 CoreCLR(.NET Core 运行时)。除非你真的想构建一个 UWP 应用程序,否则你不需要考虑这个问题,因为 .NET Native 中的反射会发生各种有趣的事情,需要应用程序开发人员单独关注。

现在我们来到 .NET Core! .NET Core 最初是“ASP.NET Core”,但人们很快意识到它可能比这大得多。 .NET Core 是一个新的运行时 (CoreCLR) + 库组合,具有显式跨平台支持(如跨操作系统)。与 CLR + BCL 组合不同,其中有一个 Windows 版本和一个 Mono 形式的 Unix 版本,.NET Core 是一个适用于所有平台的代码库(当然,具有特定于平台的松脆位以支持上面的蓬松可移植层) .更让人困惑的是,.NET Core 也是一个新的工具链/项目类型的名称,用于支持构建 .NET Core 应用程序,而在此之前我们只有 MSBuild。这是因为没有适用于 Linux 的 Visual Studio,但 MS 是 already moving away,来自这种“让我们保持简单和 JSON”的方法,并回到 .NET Framework 和 .NET Core 的一种通用格式(它将是 MSBuild,因为还有更多的东西)。

.NET Core 在很大程度上与 .NET Framework 非常兼容。因此,如果您的 .NET Core 应用程序实际上在 .NET Framework(在 Windows 上)上运行,它可以加载面向 .NET Framework 的程序集,而不仅仅是 .NET Core。这是混淆和不可移植代码的重要来源:虽然您可以针对这些程序集进行构建和加载,但它们会使您的代码不可移植。 .NET Core 本身不会阻止您这样做; .NET Standard(即将推出)将,如果你正确地排列你的声明。

到目前为止和我在一起?很好,因为现在我们已准备好将 .NET Standard 放在您毫无戒心的脑袋上。 .NET Standard 不是一个平台(从某种意义上说,您不能在机器上下载和安装它),它不是一个库(但有一些包支持它用于构建目的),它是一个配置文件。这是对我们刚刚讨论的各种内容的库表面进行标准化的尝试。这个想法是,如果您的代码以 .NET Standard XY 为目标,您只需将构建工具切换为“请给我 .NET Standard XY”,并且当您构建程序集时,您可以确定将可用于 XY 涵盖的所有平台万岁!世界又简单了!

嗯,还不是。问题是 .NET Core 目前正处于繁重的开发中,这意味着很多东西缺失或不同——甚至是非常基本的东西,它们可能自然存在于你的 .NET Framework 代码库中,比如标记你的异常Serializable 和为它们提供一个单独的反序列化构造函数,以便它们在AppDomains 中很好地工作。 .NET Core 中没有 AppDomains,因此没有序列化,因此这些构造函数不会编译。即使是 Serializable 属性本身也在旧版本的 CoreCLR 中丢失。如果您的 MSBuild 项目使用自定义目标,那太糟糕了,.NET Core 工具链目前不支持这些东西(它可能在将来再次成为 MSBuild 时)。当然,您可以重写,但不能重用。因此,虽然您可以以 .NET Standard 为目标,但您可能需要两个单独的项目和/或一些条件编译来获得适用于两个不同平台的 .NET Standard 程序集。如果你很幸运(或者可以妥协一点),你的库足够简单,仅使用 .NET Core 构建它就足够了。但请不要误会:仍然有多个 .NET 平台,它们仍然存在差异,.NET Standard 只是试图使其更容易移植。到目前为止,它是有限的,但已经比 PCL 做得更干净了。

总结一下:.NET Core 和 .NET Framework(以及它们的所有小表亲和侄子)在概念上和实现上都是独立的平台。 .NET Standard 是一种目标配置文件,可简化在它们之间移植代码所需的工作(但尚未使其完全透明)。 PCL 是标准的前身,如果你是进步主义者,可以忽略它。


TL;DR 从这里开始(但仍然是 TL)

为了最终回答您的问题,如果您是一名现代图书馆开发人员,并且您想针对“尽可能多的受众”,您应该怎么做?首先,如果可能,您必须将其缩小。您将明确支持和测试哪些平台?您真的想在您的 Xbox 360 上以 .NET Compact 为目标吗?视窗电话 7?八年前的银光?如果这样做,您可能无法绕过 PCL,但我们大多数人都可以避免这种情况。如果不是:如果您的配置文件与 .NET Standard 中的任何内容都不匹配,则排队单独构建 PCL。

您的库是否非常简单(不使用反射,不使用 async/await,不依赖于 WCF 等更大的框架)?然后,您可能能够针对具有所需框架依赖项的 .NET 2.0 和 最低 版本的 .NET Standard 的横截面。不要被愚弄,.NET Standard 的低版本在提供的功能上确实令人失望,但您必须为可移植性付出一些代价。没有为 .NET 2.0 和某些 .NET Standard 版本构建的工具链支持。您必须构建它两次并在“任何地方”对其进行测试,尽管横截面意味着您可以合理地确定它在编译时会起作用。生成的库将支持每个可以加载 vanilla .NET 2.0 程序集(几乎所有程序集,但尤其不是 Micro 和 Compact)和 .NET Core 的单个 .NET 平台,并且所有平台都没有平台切换。恭喜,世界从未见过如此便携的东西!

您的库会使用反射吗?那么您可能无法绕过重写代码以使其为 .NET Core 编译,因为 reflection API changed a while back 和您的代码可能还没有赶上(因为如果您只针对完整框架,则没有必要)。在这种情况下,您需要将目标 .NET Framework 版本提升到 4.5,因为这是与这些更改兼容的 .NET Framework 版本。在这里您开始获得工具支持:您可以针对 .NET Standard 1.1,它涵盖了 .NET 4.5 的 子集。如果您发现这个子集还不够,您将不得不再次构建两次:完整的 .NET Framework 和 .NET Core。原因是 .NET Core 1.0 比 .NET Framework 4.5 支持“更多”,但目前还没有可以与 Core 相媲美的 .NET Framework 版本(即“vNext”)。因此,如果您不想仅限于 .NET Core,还想支持我们这些仍在构建普通的旧 4.5 桌面应用程序并且.NET Standard 1.1 对您来说还不够,您'将不得不分裂。错误的做法是针对 1.1,然后只导入 Framework 4.5 的包/程序集,因为这会使您在可移植性方面两全其美!

您的库是否需要在 4.5.1 或更高版本中引入的超过 4.5 的某些改进/扩展,或者仅适用于更高 .NET Standard 版本的包?然后改为以适当的更高 .NET Standard 版本为目标。请注意,微软no longer officially supports any 4.x lower than 4.5.2。这确实意味着您不应该针对那些版本(尽可能低),但它确实意味着您有理由使用不低于 . NET Standard 1.2,如果您可以要求 4.6,则不低于 1.5。这对消费者来说不是负担(如果您愿意并且能够安装 4.6,那么您几乎可以肯定愿意并且能够安装 4.6.2)并使您的生活更轻松。根据您的代码,您可以只使用 .NET Core 构建,但您可能不想这样做,因为 .NET Core 构建链还不稳定,将移回 MSBuild(如前所述)。放弃所有项目文件以使用 JSON 只是为了稍后再返回是没有意义的!

您的库是否使用任何类型的条件编译?请注意,使用 .NET Core 工具链,您会得到 different predefined symbols。他们特别烦人,因为他们坚持(比如说)区分 4.5、4.5.1 和 4.5.2,如果你想涵盖“4.5 及更高版本”,这会很痛苦。没有什么是精心构建无法处理的,但您需要考虑一些事情。

我不会在这里介绍移动版本(Xamarin 和旧手机版本),因为我对这些知之甚少!我想这个故事与为 .NET Core 和 .NET Framework 构建非常相似,因为该构建曾经只适用于简单的库和您不必关心向后兼容性和需求的库(至少)否则有两个构建,但正如我在一开始所说的那样,欢迎更正。

【讨论】:

【参考方案3】:

我先回答你的第二个问题:

我有一个针对 .Net 2.0、.Net 4.5 和 UWP 的库。针对 UWP 需要创建一个新的 VS 项目并链接所有现有文件,这是一个巨大的痛苦。现在有人告诉我它不适用于 PCL,从它的声音来看,我必须为 .Net Standard 再次这样做!?)

如果我想编写一个可供尽可能多的受众使用的库,我需要使用其中的哪一个(或多个)?

简答:你应该定位netstandard。使用具有您需要的所有 API 的 lowest version。您可以使用API Port 到check your existing project for compatibility with a given netstandard version 之类的工具。

不幸的是,这种方法将遗留旧平台,在您的情况下是 .NET 2.0。如果需要维护 .NET 2.0 支持,那么您将需要一个单独的项目(带有链接文件)来构建一个单独的 .NET 2.0 程序集。

关于细节...

有什么区别!?

.Net Standard (netstandard) - 这是新的跨平台 BCL API。它是一个“标准”,因为它只是一个 API 定义而不是实现。这个想法是,您可以将您的库编译为该 API 的(一个版本),它将在支持该版本的任何平台上运行。 .Net Core - 您可以将其视为netstandard 的参考实现(带有一些额外的位)。它是该 API 的跨平台实现。 UI 和其他框架可能会基于它构建,但目前它唯一确定的立足点是充当 ASP.NET Core 的首选平台。 [旁注:由于历史原因,“.NET Core”与netcore NuGet 目标完全不同;当您在 NuGet 上下文中时,netcore means "Windows 8/8.1/10"]。 .Net PortablePortable Class Libraries - 可移植类库 (PCL) 是提供跨平台 API 的最不常用的方法。它们涵盖了wide range of target platforms,但它们不完整且不会面向未来。它们基本上已被netstandard 取代。 .Net Compact - 这是一个完全不同的 .NET 框架,拥有自己独特的 API。它与任何其他框架、PCL 或netstandard 版本完全不兼容;因此,它比任何其他平台都难以支持。但是,它仍用于内存限制严格的设备上。 通用 Windows 平台 - 这是 Win10 时代 Windows Phone 和桌面之间的 API 合并,允许为这两个平台编写 Windows 应用商店应用程序/库。这基本上已被netstandard 取代。

【讨论】:

由于其他用户的回答如此之长,我很难将赏金提供给最短的(以及不需要代表的用户),但是给这是最完整的最简洁的答案,它绝对值得。谢谢斯蒂芬! 对于当今可以使用的最便携的代码,PCL 不是最有意义吗? @KipMorgan:仅适用于旧平台。再过一两年,答案将是“绝对不会”。 @StephenCleary 我刚刚安装了 .NET Core 2.0 SDK,现在正在使用它。我注意到没有 PCL 选项,这是因为 .NET Core 是应该替换 PCL 的 netstandard 的实现吗?如果是这种情况,.NET Core Class Library 是否能够部署在移动应用程序上(就像 PCL 一样)? Xamarin 是移动设备的“前进之路”。任何 netstandard 库都可以在最新版本的 Xamarin 上运行。如果您所说的“移动”是其他意思,那么:UWP supports netstandard1.4 and below, WPA supports netstandard1.2 and below, and WP-SL only supports netstandard1.0。 .NET Core 类库只能在 .NET Core(Windows/Linux,而不是移动设备)上运行。

以上是关于.Net Core、Portable、Standard、Compact、UWP 和 PCL 之间的区别?的主要内容,如果未能解决你的问题,请参考以下文章

gradle问题“main”groovy.lang.MissingPropertyException:没有这样的属性:类的baseDir:org.apache.catalina.core.Standa

Core DES加解密

如果不需要,建议移除net startand类库中的Microsoft.NETCore.Portable.Compatibility

sh GPS和推送通知以及速度测试来自:http://decryption.net.au/index.php/2013/10/05/raspberry-pi-portable-3g4g-network

[转]SVN安装问题The Apache Portable Runtime (APR) library cannot be found

如何将Eclipse Portable与Java Portable集成?