In C #, sizeof to calculate unmanaged type (type value) of the size, it can not be used to calculate a managed type (type reference) of the size, in bytes.
When a reference to the types of sizeof, the compiler will complain, as the code:
Console.WriteLine(sizeof(string));
Will be thrown
A, sizeof
1, except struct, the general value types may be used as the sizeof () to calculate its size, it does not involve a context security issues, such as:
Console.WriteLine(sizeof(int));//4
DETAILED sizeof is calculated as follows:
2, as for struct, if its use the sizeof () relates to the security context, such as code
public struct TestStruct { public bool TestA; public int TestInt; public bool TestB; }
// use sizeof must be hung in unsafe under the code, but also to be set up to support the project properties unsafe context mode unsafe { Console.WriteLine(sizeof(TestStruct)); }
At this time, the output byte size is 12 , not 1 + 4 + 1 = 6.
Why is it 12, which relates to memory alignment .
Memory Alignment rules can click here
TestStruct corresponding memory is: 0xxx | 0000 | 0xxx
If TestB and TestInt two lines about the swap, the following code
public struct TestStruct2
{
public bool TestA;
public bool TestB;
public int TestInt;
}
At this time TestStruct2 byte size 8 is occupied, the corresponding memory should be: 00xx | 0000
To TestStruct and share the same memory size TestStruct2, you can use TestStruct field layout [ StructLayout ( LayoutKind . Auto ) ]
[StructLayout(LayoutKind.Auto)]
public struct TestStruct
{
public bool TestA;
public int TestInt;
public bool TestB;
}
As for field layout , can be seen here
二、Marshal.SizeOf
Marshal.SizeOf returns the class size unmanaged
Marshal.SizeOf document, see the official website
To facilitate understanding, on marshaling can reference herein
I tested the code is as follows:
using System; using System.Runtime.InteropServices; namespace TestCSharp { [StructLayout(LayoutKind.Sequential)] public class TestClass { } [StructLayout(LayoutKind.Sequential)] public struct TestStruct2 { public byte by; public sbyte sb; public bool b; public char c; public short s; public ushort us; public int i; public uint ui; public long l; public ulong ul; public float f; public double d; public decimal dec; public TestClass tc; } internal class Program { public static void Main(string[] args) { TestStruct2 t = new TestStruct2(); t.tc = new TestClass(); Console.WriteLine(Marshal.SizeOf(t.by));//1 Console.WriteLine(Marshal.SizeOf(t.sb));//1 Console.WriteLine(Marshal.SizeOf(t.b));//4 Console.WriteLine(Marshal.SizeOf(t.c));//1 Console.WriteLine(Marshal.SizeOf(t.s));//2 Console.WriteLine(Marshal.SizeOf(t.us));//2 Console.WriteLine(Marshal.SizeOf(t.i));//4 Console.WriteLine(Marshal.SizeOf(t.ui));//4 Console.WriteLine(Marshal.SizeOf(t.l));//8 Console.WriteLine(Marshal.SizeOf(t.ul));//8 Console.WriteLine(Marshal.SizeOf(t.f));//4 Console.WriteLine(Marshal.SizeOf(t.d));//8 Console.WriteLine(Marshal.SizeOf(t.dec));//16 Console.WriteLine(Marshal.SizeOf(t.tc));//1 Console.WriteLine(Marshal.SizeOf(t));//80,#pragma pack(n) 表示设置为n字节对齐。 C#默认应该也是8字节对齐(没有查证),所以t.dec应该是按照8而不是16对齐,这个需要注意 } } }
这个是测试输出的字节大小
其中类的封送不能用[StructLayout(LayoutKind.Auto)],可以改成[StructLayout(LayoutKind.Sequential)]
Marshal.SizeOf所得大小也是按内存对齐规则来的
另:如果sizeof(TestStruct)没有放在unsafe下,如
Console.WriteLine(sizeof(TestStruct));
会有编译错误:
解决办法是:
unsafe
{
Console.WriteLine(sizeof(TestStruct));//用sizeof必须要挂在unsafe 代码下,而且工程属性要设置为支持上下文不安全模式
}
别忘记工程属性要设置为支持上下文不安全模式,否则会报如下编译错误: