【发布时间】:2011-07-24 00:22:33
【问题描述】:
由于 DateTime 是一个结构,其成员似乎分解为简单的数学值,我不确定为什么在其上使用 sizeof() 会在问题标题中产生消息。
【问题讨论】:
标签: .net datetime struct size sizeof
由于 DateTime 是一个结构,其成员似乎分解为简单的数学值,我不确定为什么在其上使用 sizeof() 会在问题标题中产生消息。
【问题讨论】:
标签: .net datetime struct size sizeof
因为 CLR 只能在运行时确定大小...其中一个原因是“填充”(取决于平台)...
对于所有其他类型,包括结构,sizeof 运算符可以是 仅在不安全的代码块中使用。虽然您可以使用 Marshal.SizeOf 方法,该方法返回的值并不总是 与 sizeof 返回的值相同。 Marshal.SizeOf 返回 类型被编组后的大小,而 sizeof 返回 大小 因为它已由公共语言运行时分配, 包括任何填充。
Ref.
另见How do I check the number of bytes consumed by a structure?
【讨论】:
sizeof(DateTime) 在unsafe 上下文中可以正常工作(请参阅我的新答案)。
Marshal.sizeof() 在需要知道托管代码中类型的实际大小的情况下是必须准确的,例如在决定如何细分大型集合以避免大对象堆分配。 sizeof() 使用的 CIL 操作码实际上适用于任何托管类型(类类型存储位置的大小将报告为对象引用的大小,这正是避免 LOH 所需的信息)。不幸的是,C# 的设计者决定程序员不应该访问这些信息。
你得到的完整错误文本是:
错误 CS0233:“System.DateTime”没有预定义的大小,因此 sizeof 只能在不安全的上下文中使用(考虑使用 System.Runtime.InteropServices.Marshal.SizeOf)
因此,如果您确实使用unsafe 上下文(请务必转到 C# 项目的“属性”,“构建”选项卡,并在“允许不安全代码”中设置复选标记以使以下代码编译)它可以工作很好:
static void Main()
{
int s;
unsafe
{
s = sizeof(DateTime);
}
Console.WriteLine(s); // writes 8
}
使用unsafe 关键字,sizeof() 将适用于所有enum 类型以及所有没有引用类型实例字段的struct 类型(并且DateTime 是一个没有引用类型成员的结构,当然)。
没有unsafe 关键字,您就不能使用sizeof。 (但是,从 C# 2 开始,您可以在 int 和 enum 类型等预定义类型上使用它,但不能在 DateTime 等其他结构上使用它,如您所见。)
请注意,DateTime 结构是例外的,因为 Marshal.SizeOf<DateTime>()(或 .NET 版本 4.5.1 (2013) 之前的 Marshal.SizeOf(typeof(DateTime)))将引发异常。这是因为不寻常的(对于struct)结构布局“自动”。
【讨论】:
Alex Pinsker 写了nice solution 以获得DateTime(或任何其他类型)的大小。
【讨论】: