8

Since DateTime is a struct with members that appear to break down into simple mathematical values, I'm not sure why using sizeof() on it produces the message in the question title.

0

3 Answers 3

8

Because the CLR can only determine the size at runtime... one of the reasons for this is "padding" (platform dependent)...

For all other types, including structs, the sizeof operator can be used only in unsafe code blocks. Although you can use the Marshal.SizeOf method, the value returned by this method is not always the same as the value returned by sizeof. Marshal.SizeOf returns the size after the type has been marshaled, whereas sizeof returns the size as it has been allocated by the common language runtime, including any padding.

Ref.

see also How do I check the number of bytes consumed by a structure?

3
  • Thanks :-) Added a second reference
    – Yahia
    Commented Jul 24, 2011 at 0:32
  • This also implies that sizeof(DateTime) will work fine in unsafe context (see my new answer). Commented Feb 19, 2014 at 13:30
  • I don't think Marshal.sizeof() is necessary accurate in the cases where one needs to know the actual size of a type in managed code, such as when deciding how finely to subdivide a large collection to avoid Large Object Heap allocations. The CIL opcode which sizeof() uses would actually work just fine with any managed type (the size of class-type storage locations would be reported as the size of an object reference, which is precisely the information necessary needed for LOH avoidance). Unfortunately, the designers of C# decided programmers shouldn't have access to such information.
    – supercat
    Commented May 24, 2014 at 20:45
2

The full error text you get, is:

error CS0233: 'System.DateTime' does not have a predefined size, therefore sizeof can only be used in an unsafe context (consider using System.Runtime.InteropServices.Marshal.SizeOf)

So if you do use unsafe context (be sure to go to the C# project's "Properties", the "Build" tab, and set a check mark in "Allow unsafe code" to make the below compile) it works fine:

    static void Main()
    {
        int s;
        unsafe
        {
            s = sizeof(DateTime);
        }
        Console.WriteLine(s); // writes 8
    }

With the unsafe keyword, sizeof() will work with all enum types and with all struct types that do not have instance fields of reference type (and DateTime is a struct with no reference type members, for sure).

Without the unsafe keyword, you cannot use sizeof. (However, since C# 2 you are allowed to use it on pre-defined types like int and on enum types, but not on other structs like DateTime, as you saw.)


Note that the DateTime struct is exceptional in that Marshal.SizeOf<DateTime>() (or Marshal.SizeOf(typeof(DateTime)) prior to .NET version 4.5.1 (2013)) will throw an exception. This is because of the unusual (for a struct) structure layout "Auto".

0

Alex Pinsker wrote nice solution for getting the size of DateTime (or any other type).

Not the answer you're looking for? Browse other questions tagged or ask your own question.