[英]Difference between .Net Core, Portable, Standard, Compact, UWP, and PCL?
我听说过
所有这些都被解释为“完整.Net的一个子集,允许您定位多个平台” 。 所以我的问题是
(我的具体情况:我有一个针对.Net 2.0,.Net 4.5和UWP的库。针对UWP需要创建一个新的VS项目并链接所有现有文件,这是一个巨大的痛苦。现在有人告诉我它没有不适用于PCL,从它的声音我必须再次为.Net标准!?)
我先回答你的第二个问题:
我有一个针对.Net 2.0,.Net 4.5和UWP的库。 针对UWP需要创建一个新的VS项目并链接所有现有文件,这是一个巨大的痛苦。 现在有人告诉我它对PCL不起作用,从它的声音我必须再次为.Net标准做!?)
如果我想编写一个可供尽可能多的受众使用的库,我需要使用哪一个(或多个)?
简短的回答:你应该以netstandard
目标。 使用包含所需API的最低版本 。 您可以使用API端口等工具检查现有项目是否与给定的netstandard
版本兼容 。
不幸的是,这种方法将留下旧的平台,在您的情况下,.NET 2.0。 如果需要维护.NET 2.0支持,那么您将需要一个单独的项目(带有链接文件)来构建单独的.NET 2.0程序集。
关于细节......
有什么不同!?
netstandard
) - 这是新的跨平台BCL API。 它是一个“标准”,因为它只是一个API定义,而不是一个实现。 我们的想法是您可以将库编译为此API的(版本),它将在支持该版本的任何平台上运行。 netstandard
的参考实现(带有一些额外的位)。 它是该API的跨平台实现 。 UI和其他框架可能构建在它上面,但是现在它唯一可靠的立足点是作为ASP.NET Core的首选平台。 [旁注:由于历史原因,“.NET Core”与netcore
NuGet目标完全不同 ; 当你在NuGet上下文时, netcore
意味着“Windows 8 / 8.1 / 10”] 。 netstandard
取代。 netstandard
版本完全不兼容; 因此,支持比任何其他平台都困难得多。 但是,它仍然在具有严格内存限制的设备上使用。 netstandard
取代。 正如评论中所链接的那样,Microsoft已经描述了所有这些信息。 但是,根据你的回答,似乎你并没有完全理解整个事情。 它很长,所以这里(希望)是一个tl; dr版本。
我们将从上面链接的下表开始,希望这将消除一些混乱:
稍后对其他人发现的概述:.NET库在其存在的15年中经历了很多变化和端口。 在那段时间里,许多智能手机现在几乎与2001年使用的一些桌面一样强大。在这个国际米兰中, .NET框架的子集被创建(并且很快被放弃)用于不同的平台。 随着Satya Nadella将.NET作为尽可能广泛的平台的新方法,需要改变一些事情。
作为一项已有15年历史的技术,需要改进。 自2014年以来, .NET Core一直是.NET架构的彻底改革之一。 它已经从头开始重写为.NET语言的新版本。 Core的目标之一是实现跨平台部署。 无论是在iPhone / Android / XBox One上运行的应用程序,还是可以在IIS或Linux机器上托管的网站,.NET Core都能满足您的需求。 它通过几种不同的方式实现这一点,包括不需要在机器上安装.NET Framework,而是使用您的解决方案打包必要的库。
最值得注意的是,.NET Core是对ASP.NET的重大改变。 旧的System.Web完全消失并重写为尽可能高效,效果令人印象深刻 。 单独的WebApi控制器已经消失,因为一切都在一个控制器内完成。 整个过程现在是选择加入,而不是默认允许您可能不想要的事情。
但是,我们作为开发人员最终会想要迁移一些应用程序,那么我们如何确保我们已经编写的代码没有对方法进行一些小的名称更改,从而打破了巨型解决方案的编译? 来自.NET标准 。 这是一组必须实现的API,以便您的平台将自己称为“.NET”。
作为我们多年来一直使用的基本.NET框架已经很成熟,它被用作标准将包含的基础。 但是,一切都不包括在内,重点是什么? 因此,标准只是各种类型的.NET平台之间存在的通用API。 您最终不会在“.NET Standard”中编写代码。
Xamarin(包含在上表中)于2016年被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版本的情况相同。
但是,有一些教程允许您将项目移植到Core。 在大多数情况下,只需将类主体复制到.NET Core解决方案中,大多数东西都能正常工作。 有些部分已经被废弃,有些部分尚未完全100%充实(不适用于您的情况,但实体框架并不具备所有相同的功能)。 还有一些电话改变了一点点。
好的新东西是向前发展,.NET Core将为您提供最广泛的可能性。 .NET Framework不会消失,但它和Core将更加同步。
.NET Core的另一个好处是它使用迭代方法进行部署,因此您不会等待2年时间进行下一次重大升级。 通过NuGet提供的一切,您将在改进和新功能上实现更快的转变。
我假设你已经用漂亮的表读过微软的文章,现在一切都很清楚。 如果是这样的话,你和我之前在同一条船上度过了一个下午的大部分时间(并尝试将我的反思重型库移植到.NET Core,我应该提到它也是我唯一的 .NET)核心移植工作)。 接下来的不是官方派对,而是我通过大量阅读(以及自.NET 1.0以来成为.NET开发人员)所发现的内容。 我无法保证其完全准确性(特别是涉及移动开发时,我几乎完全无知)并且肯定会更正。 如果有很多我会把它做成维基。
我会或多或少地按时间顺序浏览它,因为我发现如果你想了解新旧有何关联,那就最有意义了。 它可能应该减少很多,但目前我没有时间这样做。 有一个TL; DR版本在最后,虽然。
尽管它具有Java系统,但.NET从未真正尝试过“一次编写,随处运行”。 它开始于Windows的阵营,即使它编译为字节码并且没有过度使用明确的Windows主义,因此理论上非常便携,这不是MS真正感兴趣的。部分.NET Framework是早期开源,一群开源的enthousiast选择了它并与它一起运行,给我们Mono 。 Mono很重要,因为它是.NET的第一个备用平台和库集 ,并说明了平台与库与工具链的思想。 Mono尝试提供公共语言运行时的(或多或少)完整实现,以及它的关联基类库。 这很重要:虽然Mono在Linux(以及其他一些Unices)上运行,但它并不是一个单独的平台,因为它实现了CLR + BCL(某些版本)。 存在与应用程序开发人员相关的运行时差异(路径名称等),但对于实际的库编程,您可以将Mono和.NET Framework for Windows视为“相同”的平台,实现略有不同。 我强调这一点是因为我们将遇到针对未在CLR上运行的Windows的.NET代码,并且(具有讽刺意义或其他方面)难以移植。
然后出现了Windows Phone(多个版本),Windows CE(多个版本),Windows Embedded CE,Windows Toaster(好的,那个实际上并不存在),并且每次基本上都重新发明了.NET的某些风格 - 仍然是.NET但是运行时和/或BCL的基本内容缺失或改变了。 这是我们获得.NET Compact , .NET Micro , Windows Phone (旧样式,框架没有单独名称)和Silverlight的地方 。 所有这些都应该被认为是类似于.NET Framework的独立平台+库组合,足以使跨平台开发成为可能,但不同于它足以使它变得不那么容易 。 为了跟踪支持共享库最不方便的内容,有人提出了可移植类库及其相关配置文件(其集合称为.NET可移植参考组件 )的概念。
基本上,您定位一组.NET版本,平台(和库)的特定组合,并且您将获得模仿这些组合以进行编译的参考程序集。 根据您明确希望定位的口味,存在许多不同的配置文件。 这是.NET Standard现在尝试更大规模的第一次尝试。 基本上, PCL现在已经过时了,除非你的目标是.NET Standard没有试图支持的东西 。 .NET标准不再考虑大量不同的配置文件,这样做很好,但却牺牲了你的库可以早先定位的一些东西,这很糟糕。 有在线资源可以帮助从PCL过渡到.NET Standard。 如果你现在正在寻找可移植的代码,你不想把重点放在PCL,除非你真的想支持一些漂亮的边际平台(无犯罪意图的人对他们仍处于发展阶段)。
顾名思义, 通用Windows平台是一个平台。 具体来说,Windows Store应用程序(桌面和手机)都支持.NET平台。 就是这样,不多也不少。 它最好被认为是Silverlight的自然继承者,因为它是桌面和移动设备的沙盒框架支持。 尽管有这个名字,但它并不是一个通用的平台,它不是你想要的所有代码所针对的。 它是您可能希望为您的代码启用的平台,它的独特之处在于它是我所知道的唯一一个在同一版本中具有两个运行时的平台。 马上就来!
原始帖子中没有提到.NET Native ,但是经常出现在这些讨论中,因为它也是新的,比如.NET Core,听起来非常性感,因为它直接将.NET编译为机器代码(提前编译,而不是JIT编译)。 在发布模式下编译时,它不是一个完整的新平台,而是UWP应用程序的新运行时(仅限于那些)。 在调试模式下,它们使用CoreCLR(.NET Core运行时)。 除非你真的想要构建一个UWP应用程序,否则你不需要考虑这个问题,因为.NET Native中的反射会发生各种有趣的事情需要应用程序开发人员的单独关注。
现在我们来到.NET Core ! .NET Core起初是“ASP.NET核心”,但人们很快意识到它可能比这更大。 .NET Core是一个新的运行时(CoreCLR)+库组合,具有明确的跨平台支持(如跨操作系统)。 与CLR + BCL组合不同,其中有Windows版本和Mono形式的Unix版本,.NET Core是所有平台的一个代码库(当然,通常平台特定的脆弱位支持蓬松的便携层) 。 令人困惑的是.NET Core 也是支持构建.NET Core应用程序的新工具链/项目类型的名称,之前我们只有MSBuild。 这是必需的,因为没有Visual Studio for Linux,但MS 已经摆脱了“让我们保持简单和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标准XY”,并且在构建程序集时,您可以确保它可用于所有平台由XY万岁覆盖! 世界又变得简单了!
好吧,还没有。 问题是.NET Core目前处于大量开发阶段,这意味着很多东西都缺失或不同 - 甚至是.NET Framework代码库中可能存在的非常基本的东西,比如标记您的异常Serializable
并给予它们用于反序列化的单独构造函数,以便它们可以在AppDomain
很好地工作。 .NET Core中没有AppDomain
,因此没有序列化,因此这些构造函数将无法编译。 在旧版本的CoreCLR中,甚至缺少Serializable
属性本身。 如果您的MSBuild项目使用自定义目标,那么.NET Core工具链目前不支持这些内容(将来可能再次使用MSBuild)。 当然,您可以重写,但不能重复使用。 因此,虽然您可以定位.NET Standard,但您可能需要两个单独的项目和/或一些条件编译来为两个不同的平台获取.NET Standard程序集。 如果你很幸运(或者可以妥协一下),你的库很简单,只用.NET Core构建它就足够了。 毫无疑问:仍有多个.NET平台,它们仍然存在差异,.NET Standard只是试图让它更容易移植。 到目前为止它有限,但已经比PCL做得更干净。
总结一下:.NET Core和.NET Framework(以及他们所有的小表兄弟和侄子)在概念上和实现上都是独立的平台。 .NET Standard是一种定位配置文件,可简化在它们之间移植代码所需的工作(但尚未使其完全透明)。 PCL是标准的前身,如果你是进步的话可以被忽视。
要最终回答您的问题,如果您是一名现代图书馆开发人员,并且希望“尽可能多的受众”,您应该怎么做? 首先,如果可能的话,你必须让它变小。 您将明确支持和测试哪些平台? 您真的想在XBox 360上使用.NET Compact吗? Windows Phone 7? 八年前的Silverlight? 如果你这样做,你可能无法绕过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编译,因为反射API改变了一段时间后你的代码可能还没有赶上(因为没有必要,如果你继续瞄准完整的框架)只要)。 在这种情况下,您需要将目标.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支持“更多”,但是目前还没有.NET Framework的版本可以与Core(即“vNext”)相提并论。 因此,如果您不想仅限于.NET Core,而且还希望支持我们这些仍然构建普通的旧4.5桌面应用程序并且 .NET Standard 1.1对您来说还不够,那么您将不得不拆分。 错误的做法是目标1.1,然后只导入Framework 4.5包/程序集,因为这将使您在可移植性方面成为最糟糕的两个世界!
您的库是否需要4.5.1或更高版本中引入的4.5以上的一些改进/扩展,或仅适用于更高.NET标准版本的软件包? 然后定位适当的更高的.NET标准版本。 请注意,Microsoft 不再正式支持低于4.5.2的任何4.x. 这并不意味着你不应该针对这些版本(尽可能的低,你可以合理的),但它确实意味着你有一个论据使用无外乎.NET 1.2的标准,如果你可以要求4.6,不小于1.5。 这对消费者来说并不累赘(如果你愿意并且能够安装4.6,你几乎肯定愿意并且能够安装4.6.2)并且让你的生活更轻松。 根据您的代码,您可以只使用.NET Core构建,但您可能不想这样做,因为.NET Core构建链尚未稳定并将返回到MSBuild(如前所述)。 放弃JSON的所有项目文件只是为了以后再回来!
您的库是否使用任何类型的条件编译? 请注意,使用.NET Core工具链,您可以获得不同的预定义符号 。 他们非常讨厌,因为他们坚持(比如说)区分4.5,4.5.1和4.5.2,如果你想要涵盖“4.5及以上”,那将是一种痛苦。 没有任何细心的构建无法处理,但您需要考虑的事情。
我不是在这里介绍移动版本(Xamarin和旧手机版本)因为,我对这些知之甚少! 我想这个故事与构建.NET Core和.NET Framework非常相似,因为该构建只适用于简单的库和库,您不必关心向后兼容性,并且需要(至少)否则两个构建,但正如我在开始时说的那样,欢迎更正。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.