sizeof() vs Marshal.SizeOf()

By | 2018-03-18

To get the size of a data type in .Net you can use sizeof()  or Marshal.SizeOf() .

I’ll briefly explain the difference between the two.

sizeof()

sizeof()  (MSDN) can only be used on data types that have a known size at compile-time. It is compiled as a constant. If you attempt to use it on invalid data types you get a compiler error CS0233.

This means it has zero overhead during execution.

Example

Compiles to IL code:

Marshal.SizeOf()

System.Runtime.InteropServices.Marshal.SizeOf()  (MSDN) however works on struct data types at runtime by measuring their size. This means both the overhead of calling the method, as well as extra work for boxing and measuring.

Example

Compiles to IL code:

Peeking inside

If we look at the source code (referencesource)

From this we can see that the struct will be measured by external API call. If Type is provided, extra checks are made. If object is provided as parameter boxing from struct to object occurs.

Caveats

In two cases Marshal.SizeOf<T>()  will differ from sizeof(T) .

This has to do with how .Net marshals data types to unmanaged code.

Managed data type Char (2 bytes) is identified as Windows type SBYTE (1 byte), and managed data type Boolean (1 byte) is identified as windows type BOOL (4 bytes).

One thought on “sizeof() vs Marshal.SizeOf()

  1. oddbear

    If the you point to a struct in another assembly, the IL of sizeof would be similar to this ‘IL_0000: sizeof SizeTesting.Test’.
    If you then change the library dll, the value also gets updated. So in this case, it would happen in runtime and not in compile time.

    int size;
    unsafe
    {
    size = sizeof(Test); //struct Test in another assembly.
    }

    Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.