How to find the size of a class in C#

2019-01-26 05:26发布

问题:

public class A
{
  int x;
  float y;
}

How to find the size of the class in C#. Is there any operator like Sizeof(), which used to be in C++

回答1:

Short answer:

You dont.

Long answer:

You can only do that if you type has a fixed layout and has no managed members. Structs are fixed by default. Classes can attributed to have a fixed layout.

(I am not showing how, as you really do not need it. It is only important when doing interop.)



回答2:

The following would give you the size of the C# class:

Marshal.SizeOf(typeof(Myclass));

using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
class Myclass
{

}

Remember size of a class depends on padding.



回答3:

You could serialize the class into a memory stream and then get the size from there, but I wouldn't really recommend doing this unless you had to.



回答4:

If you use the sizeof operator, you'll get the size of the pointer (which will be the same for all objects, obviously).

You could write your own method and iterate (using reflection) over all the object's members (or the ones you're interested in) and add the size of each individual member.

The tricky part would be able to determine the size of member that are not native types... your method would have to be somewhat "recursive".

If you were to implement the above idea, you'd have the approximate size of the object.



回答5:

Most of the posted solutions are great and work fine but they have the restriction that your class must be serializable (for more details see: https://docs.microsoft.com/en-us/dotnet/standard/serialization/basic-serialization) However if you class is not serializable then the following code can be helpful. This code takes into consideration the fact that using a reference field is not free it adds some overhead. It also considers using an average size for strings so you get a better approximation.

    /// <summary>
    /// Gets the size of object.
    /// </summary>
    /// <param name="obj">The object.</param>
    /// <param name="avgStringSize">Average size of the string.</param>
    /// <returns>An approximation of the size of the object in bytes</returns>
    public static int GetSizeOfObject(object obj, int avgStringSize=-1)
    {
        int pointerSize = IntPtr.Size;
        int size = 0;
        Type type = obj.GetType();
        var info = type.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
        foreach (var field in info)
        {
            if (field.FieldType.IsValueType)
            {
                size += System.Runtime.InteropServices.Marshal.SizeOf(field.FieldType);
            }
            else
            {
                size += pointerSize;
                if (field.FieldType.IsArray)
                {
                    var array = field.GetValue(obj) as Array;
                    if (array != null)
                    {
                        var elementType = array.GetType().GetElementType();
                        if (elementType.IsValueType)
                        {
                            size += System.Runtime.InteropServices.Marshal.SizeOf(field.FieldType) * array.Length;
                        }
                        else
                        {
                            size += pointerSize * array.Length;
                            if (elementType == typeof(string) && avgStringSize > 0)
                            {
                                size += avgStringSize * array.Length;
                            }
                        }
                    }
                }
                else if (field.FieldType == typeof(string) && avgStringSize > 0)
                {
                    size += avgStringSize;
                }
            }
        }
        return size;
    }


标签: c# class size