开发者

How to find the size of a class in C#

public c开发者_运维技巧lass 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++


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.


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.)


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.


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://learn.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;
    }


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜