如何在 C# 中查找类的大小

发布于 2024-08-23 01:55:58 字数 113 浏览 3 评论 0原文

public class A
{
  int x;
  float y;
}

如何在 C# 中查找类的大小。 C++ 中是否有像 Sizeof() 这样的运算符

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++

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

月下客 2024-08-30 01:55:58

下面将为您提供 C# 类的大小:

Marshal.SizeOf(typeof(Myclass));

using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
class Myclass
{

}

请记住,类的大小取决于填充。

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.

烟雨凡馨 2024-08-30 01:55:58

简短回答:

你不知道。

长答案

仅当您的类型具有固定布局且没有托管成员时,您才能执行此操作。结构默认是固定的。类可以归因于具有固定的布局。

(我没有展示如何操作,因为您确实不需要它。它仅在进行互操作时才重要。)

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

眼泪也成诗 2024-08-30 01:55:58

您可以将类序列化到内存流中,然后从那里获取大小,但除非迫不得已,否则我真的不建议这样做。

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.

朱染 2024-08-30 01:55:58

大多数发布的解决方案都很棒并且工作正常,但它们有一个限制,即您的类必须可序列化(有关更多详细信息,请参阅:https://learn.microsoft.com/en-us/dotnet/standard/serialization/basic-serialization)
但是,如果您的类不可序列化,那么以下代码可能会有所帮助。
这段代码考虑到了这样一个事实:使用引用字段并不是免费的,它会增加一些开销。
它还考虑使用字符串的平均大小,以便您获得更好的近似值。

    /// <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;
    }

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;
    }
半﹌身腐败 2024-08-30 01:55:58

如果您使用 sizeof 运算符,您将获得指针的大小(显然,对于所有对象来说,该大小都是相同的)。

您可以编写自己的方法并迭代(使用反射)所有对象的成员(或您感兴趣的成员)并添加每个单独成员的大小。

棘手的部分将能够确定不是本机类型的成员的大小......您的方法必须有点“递归”。

如果您要实现上述想法,您就会得到该对象的大致大小。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文