可移植类库实际解决了什么问题?

22

我在想,PCL解决了什么问题?如果它所做的只是限制我使用跨平台的类型,那么为什么Microsoft不在IDE中通过标准.NET库中添加此功能呢?

基本上,我可以轻松编译包含一些POCO对象的.NET库,并将该DLL引用到我的Silverlight、WPF和Windows Store应用程序中,而无需重新编译或遇到任何问题。是否有任何在PCL中工作但在标准.NET库中无法工作的代码的硬性示例?


哦,我知道显然有一些在标准.NET库中可以工作的东西,我不关心那个... 我的问题是:

是否有任何代码可以在可移植类库中编译,并且如果完全相同的代码放在.NET库中,它将无法正常工作?


1
它允许您支持多个版本的.NET Framework,而无需创建项目的多个版本。否则,您需要一个单独的项目来针对WPF和Windows Store。 - Security Hound
@Ramhound:我理解它的目标,但我希望能够得到一个真正的代码示例,该示例只能在PCL(编译一次)中正确运行,而不能在标准.NET库(编译一次)中正确运行。如果我强制自己只使用跨平台的类和方法,难道我不能使用标准的.NET库吗?请仔细阅读问题,我是在问是否相同的代码在PCL中可以正常工作,但在.NET库中无法正常工作。 - michael
你的想法是只使用存在于多个 .NET Framework 版本中的类,这正是可移植类库所做的。.NET 代码就是 .NET 代码。 - Security Hound
@Ramhound:我不确定这是否正确……可能是……但如果我没记错,PCL编译的程序集略有不同……例如,它们的可重定向标志设置为“是”。我认为可能存在一些在PCL中适用但在标准.NET库中不适用的代码情况,只是我现在想不起来了。 - myermian
@m-y - 没有的原因是你只需要针对支持代码的平台进行定位。 - Security Hound
5个回答

22

有两件事:

首先,如果你的意图是创建一个可以在多个平台上工作的库,你不希望在运行时发现你意外地使用了一个不适用于所有平台的API(通过TypeLoadException或MissingMethodException等方式)。因此,可移植类库仅会为你提供支持所有目标平台的API的智能感知,而对于那些不在该范围内的API,你将会得到构建错误。

其次,如果你创建一个只使用在所有平台上都可用的API的.NET Framework库,所创建的DLL仍然无法在其他平台(例如Windows Phone和Silverlight)上工作,除非将其编译为这些平台的库。虽然这听起来似乎是合理的期望,但过去这并不是真实的情况。可移植类库正是我们解决这个问题的方法(实际上,如果你创建一个针对Windows Store应用的类库,并且只使用适用于.NET Framework和WP8的API,则生成的二进制文件将会在这两个平台上无需任何修改即可使用)。


2
我的猜测是OP想知道PCL是否有更多功能,而不仅仅是限制Intellisense,其实确实是有的... :) - myermian
2
这可能是PCL的一些目标,但它们还没有实现。.Net Framework和Silverlight/WP7都有SocketIPEndPoint等类。然而,PCLs没有这些类。.Net Framework+XNA、Silverlight5和WP7都有Vector3Matrix等类,但是PCLs中没有。除了一堆不兼容的框架之外,现在我们还有30个不太兼容的配置文件。我仍然想知道,对于我的将两个整数相加的函数来说,哪里需要使用PCLs才能实现可移植性…… - Ark-kun
@Ark-kun 请查看http://blogs.msdn.com/b/dsplaisted/archive/2012/08/27/how-to-make-portable-class-libraries-work-for-you.aspx,了解一些API不可移植的常见原因。总的来说,Silverlight和WP7并没有真正考虑到PCL。从.NET 4.5、.NET for Windows Store应用程序和Windows Phone 8开始,您会发现几乎所有可在多个平台上使用的API都可以在这些平台之间进行移植。 - Daniel Plaisted
你贴出的链接与我所写的内容毫无关联。我已经提供了PCL问题的具体示例。".NET for Windows Store apps, and Windows Phone 8"。你对真实或被认为的不可移植性的解决方案是创建一个完全新的、强制不兼容的系统,故意破坏向后兼容性。创建另一个在Windows 7或WP7上不可用的API,这并不具备可移植性。 - Ark-kun
@DanielPlaisted,这将是我的最后两个问题:Vector2类中有什么非可移植性,它封装了一对浮点坐标?BCL团队是否认为,在经过十多年的.Net开发之后,没有普遍可用和使用的结构来封装一对浮点坐标是可以接受的? - Ark-kun
Ark-kun,一个含有几个浮点数的类本身并没有不可移植性问题;唯一的问题是各平台对 System.Object 所在位置的协议不同。Silverlight 搭载了一个不同于 .NET Framework 的 mscorlib 身份标识(这是在我加入之前决定的)。为旧版平台添加可移植支持有局限性的,因为我们试图在大门关闭后添加可移植性支持。随着我们平台的新版本发布,可移植性已经内置,这就是为什么 .NET Framework 4.5、Windows Phone 8 和商店应用程序上表现更好的原因。 - David Kean

5
我不会太担心代码本身,只需尝试以下操作,看看为什么可移植类库很有用。
1. 创建一个标准的.NET 4.5类库(它可以是空的/不包含任何类)。 2. 创建一个Silverlight 5应用程序。 3. 尝试从Silverlight 5应用程序中引用.NET 4.5类库。
你将收到以下错误消息:
“您无法添加对Demo.Utils.dll的引用,因为它未构建针对Silverlight运行时。Silverlight项目只能使用Silverlight程序集。”
那本身只是品尝“为什么”便携式类库如此出色的一小部分。困难在于试图使代码适应平台无关性,这听起来很容易,但实际上并不像你想象的那样容易。相信我,当您第一次尝试从文件夹中读取文件并意识到PCL不允许使用FileInfo时,您会感到沮丧,但Microsoft的指导意见是将平台依赖项抽象化并注入实现实际处理它的接口的类。事实上,这里有一篇不错的文章

另一篇有用的文章介绍了PCL的内部工作原理。这篇文章将帮助您理解为什么PCL能够针对多个平台。https://www.simple-talk.com/blogs/2013/04/19/inside-portable-class-libraries/


1
那本身只是一个味道,说明可移植类库为什么如此出色。我认为PCL试图解决本不应存在的问题,但未能做到。 - Ark-kun
“我认为PCL试图解决本不应该存在的问题” - 问题怎么可能不存在呢?在不同平台上拥有完全相同的API是不切实际的。使整个.NET API平台无关是一项巨大的任务,几乎最好只支持单个平台。这也是为什么苹果只支持自己的硬件,因为他们可以控制每个方面,并让开发人员使用语言和API的全部功能的原因。 - Anshul

3

我制作了一个简单的关于什么是可移植类库的YouTube视频,您可以从这里查看:http://www.youtube.com/watch?v=DcBfjdDHlxo

但是,让我在这里详细回答。创建类库项目的整个目的是可重用性。现在我们希望这种可重用性不仅在.NET应用程序内部,而且跨越.NET应用程序以及.NET应用程序的不同类型。现在不同类型的.NET应用程序包括WPF、Windows、Silver light、Windows手机等。 enter image description here

现在,每种应用程序类型都有不同的.NET框架。

例如,在Silverlight应用程序中,如果您尝试引用一个简单的“Class project”,您将遇到以下错误。这就是可移植类库有用的地方。通过创建一个可移植类库,我们可以在任何类型的.NET项目中引用它。


2
便携式类库实际上解决了什么问题?
最终,它将解决很多问题!(像Java一样,但在这个世纪)。
在便携式类库中编译的任何代码,如果完全相同的代码在.NET库中,是否会导致功能不正确?
按原则来看,我认为不会,难道不是另一种情况吗?
但是,我认为你可能真的错过了重点。
想想复制/粘贴代码、项目克隆、链接代码、条件编译器指令(甚至T4模板?)的情况,最终的结果是引用“DLL地狱”和不必要的复杂性、样板、冗长(不太优雅,对吧?)
它们不是解决二进制不兼容性的变通方法吗?
虽然现在还很早,但我认为这是一个非常棒的方向,尤其是当你看到Xamarin和Mono正在支持pcl(他们已经部分支持了),我认为这是唯一能从Html和Javascript狂热或代码生成器中拯救我们的东西。(TypeSafe永存!)
PCL也可以让C#军队摆脱Windows框。
(但这只是我的观点)

1
在使用Visual Studio 2012进行开发时,便携式类库的API与.NET Framework 4存在一些差异。主要涉及和命名空间中的一些属性和方法。有关详细信息,请参见MSDN页面this

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接