适用于 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 位存储位置上),则提供显式转换运算符。
int
、uint
和 float
全部可以隐式转换为 nint
、nuint
和 nfloat
,因为 32 位始终适合 32 位或 64 位。
nint
、nuint
和 nfloat
全部可以隐式转换为 long
、ulong
和 double
,因为 32 或 64位值始终适合 64 位存储。
必须将 nint
、nuint
和 nfloat
显式转换为 int
、uint
和 float
,因为本机类型可能保存 64 位存储的内容。
必须将 long
、ulong
和 double
显式转换为 nint
、nuint
和 nfloat
,因为本机类型可能只能保存 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
。