.NET DateTime没有预定义的大小

7

由于 DateTime 是一个结构体,其成员似乎可以分解为简单的数学值,我不确定为什么在其上使用 sizeof() 函数会产生问题标题中的消息。

3个回答

8
因为CLR只能在运行时确定大小...其中一个原因是“填充”(与平台有关)...
对于所有其他类型,包括结构体,在unsafe代码块中才能使用sizeof运算符。虽然可以使用Marshal.SizeOf方法,但此方法返回的值并不总是与sizeof返回的值相同。Marshal.SizeOf返回类型进行封送后的大小,而sizeof返回由公共语言运行时分配的大小,包括任何填充。 Ref.
另请参见如何检查结构所消耗的字节数?

谢谢 :-) 添加了第二个引用 - Yahia
这也意味着在unsafe上下文中sizeof(DateTime)将正常工作(请参见我的新答案)。 - Jeppe Stig Nielsen
我认为在需要知道托管代码中类型实际大小的情况下,例如决定如何细分大型集合以避免大对象堆分配时,Marshal.sizeof()并不是必要准确的。sizeof()使用的CIL操作码实际上可以很好地处理任何托管类型(类类型存储位置的大小将报告为对象引用的大小,这正是避免LOH所需的精确信息)。不幸的是,C#的设计者们决定程序员不应该访问这样的信息。 - supercat

2
您获得的完整错误文本如下:
错误 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))) 会抛出异常。这是由于不寻常(对于结构体来说)的结构布局“Auto”。

0

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