TL;DR 版本:更改要使用的 PackageReferenceVersion=4.0.0
,或者最低版本的项目使用的相同版本,而不是Version=4.*
.
项目和包之间存在误解。项目可以用来创建包,但它们具有不同的功能。特别是,浮动版本仅具有以下功能:PackageReference
,这就是项目定义其包依赖项的方式。文档说 https://learn.microsoft.com/en-us/nuget/reference/package-versioning#version-ranges-and-wildcards:
使用 PackageReference 格式时,NuGet 还支持对数字的 Major、Minor、Patch 和预发布后缀部分使用通配符 * 表示。 packages.config 格式不支持通配符。
也没有明确说明 nuspec 不支持通配符(包包含 nuspec,而不是PackageReferences
),但它不受支持,因此为什么你的包有依赖项>= 4.1.0.555618
。然后,正如 Matt 在评论中指出的那样,由于最近的胜利规则,您会收到降级警告(NuGet 将降级视为警告,但 .NET Core SDK 将其提升为错误。我不知道 Xamarin 是否也可以或不可以)。如果您希望您的包支持>= 4.0.0
,那么你需要改变MyCompany.FormsExtras
项目的PackageReference
for Xamarin.Forms
到版本4.0.0
(尽管您应该使用可用的最低版本的确切版本,否则每个使用您的包的项目在无法找到与您的包依赖项完全匹配的情况下都会对性能造成影响),而不是4.*
.
在通配符实现后很长一段时间我加入了 NuGet 团队,并且我没有努力寻找设计规范,所以我完全猜测,但我相信打包一个使用的项目的原因4.*
不会导致包支持>= 4.0.0
是因为 NuGet 正在尽最大努力猜测支持哪些包版本,以最大程度地减少使用该包的开发人员的运行时故障。
为了理解,考虑最极端的情况,使用通配符*
。除非 NuGet 将以某种方式使用依赖项的每个版本测试您的项目,以检查它实际上与包的哪些版本兼容(这样做完全不可行,即使是这样,打包也会变得非常慢),最简单的两个选项是要么使用>= 0.0.0
因为这在精神上等同于*
,或使用上次恢复项目时已解决的依赖项版本。
Using >= 0.0.0
是一个问题,因为如果包的第一个版本与当前版本相比可能有重大更改,或者您的项目可能使用最早版本中不可用的 API。因此,尽管您的项目使用*
,它实际上并不与该依赖项的所有版本兼容,所以>= 0.0.0
可能行不通。您的项目使用的包的版本越旧或版本越多,该包的最旧版本与您的项目配合使用的可能性就越小。
同样,语义版本控制指定次要版本表示非重大更改,但包含新的 API。您的项目已打包到使用的包中4.1.x
您的依赖关系,并且 NuGet 无法知道 1) 包是否严格符合语义版本控制(我的猜测是非常非常少)以及 2) 您的项目是否使用仅在以下版本中可用的 API:4.1.x
并不是4.0.x
。鉴于并非所有包都严格符合语义版本控制,因此即使更改也是不安全的4.1.*
to 4.1.0
.
希望我已经让您相信,当项目打包到包中时,NuGet 处理通配符的行为是最好的方法。它旨在最大限度地提高“开箱即用”的软件包的百分比。如果没有,您现在应该了解它是如何工作的,即使您不同意它是最好的实现。