适用于 iOS 和 macOS 的本机类型

Mac API 和 iOS API 都使用特定于体系结构的数据类型,这些数据类型在 32 位平台上始终为 32 位,在 64 位平台上始终为 64 位。

例如,Objective-C 在 32 位系统上将 NSInteger 数据类型映射到 int32_t,在 64 位系统上则映射到 int64_t

为了匹配此行为,在 Unified API 上,我们将以前使用的 int(它在 .NET 中定义为始终是 System.Int32)替换为新的数据类型:System.nint。 可以将“n”理解为“native”(原生),也就是平台的原生整数类型。

使用这些新的数据类型,可以为 32 位和 64 位体系结构编译相同的源代码,具体视编译标志而定。

新数据类型

下表显示了数据类型变更,以匹配这个全新的 32/64 位世界:

本机类型 32 位后备类型 64 位后备类型
System.nint System.Int32 (int) System.Int64 (long)
System.nuint System.UInt32 (uint) System.UInt64 (ulong)
System.nfloat System.Single (float) System.Double (double)

我们选择这些名称是为了让 C# 代码看起来与如今差不多。

隐式转换和显式转换

新数据类型的设计旨在允许单个 C# 源文件根据主机平台和编译设置合理使用 32 或 64 位存储。

这要求我们设计一组特定于平台的数据类型与 .NET 整型和浮点数据类型之间的隐式及显式转换。

如果不可能出现数据丢失(32 位值存储在 64 位空间上),将提供隐式转换运算符。

如果可能存在数据丢失(64 位值存储或可能存储在 32 位存储位置上),则提供显式转换运算符。

intuintfloat 全部可以隐式转换为 nintnuintnfloat,因为 32 位始终适合 32 位或 64 位。

nintnuintnfloat 全部可以隐式转换为 longulongdouble,因为 32 或 64位值始终适合 64 位存储。

必须将 nintnuintnfloat 显式转换为 intuintfloat,因为本机类型可能保存 64 位存储的内容。

必须将 longulongdouble 显式转换为 nintnuintnfloat,因为本机类型可能只能保存 32 位存储的内容。

CoreGraphics 类型

与 CoreGraphics 一起使用的点、大小和矩形数据类型根据运行它们的设备来使用 32 或 64 位。 最初绑定 iOS 和 Mac API 时,我们使用了与主机平台大小(System.Drawing 中的数据类型)匹配的现有数据结构。

移动到 Unified 时,需要将 System.Drawing 的实例替换为其 CoreGraphics 对应项,如下表所示

System.Drawing 中的旧类型 新数据类型 CoreGraphics 说明
RectangleF CGRect 保存浮点矩形信息。
SizeF CGSize 保存浮点大小信息(宽度、高度)
PointF CGPoint 保存浮点、点信息(X、Y)

旧数据类型使用 float 来存储数据结构的元素,而新数据类型则使用 System.nfloat