如何在C#中找到一个类的大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2331889/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to find the size of a class in C#
提问by Sunil
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++
如何在 C# 中找到类的大小。有没有像 Sizeof() 这样的运算符,它曾经在 C++ 中使用过
采纳答案by leppie
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.)
(我没有展示如何,因为你真的不需要它。只有在进行互操作时才重要。)
回答by Esteban Araya
If you use the sizeof
operator, you'll get the size of the pointer (which will be the same for all objects, obviously).
如果您使用sizeof
运算符,您将获得指针的大小(显然,所有对象的大小都相同)。
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.
如果您要实现上述想法,您将拥有对象的大致大小。
回答by anthonyv
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.
您可以将类序列化为内存流,然后从那里获取大小,但除非您必须这样做,否则我真的不建议这样做。
回答by Ritesh
The following would give you the size of the C# class:
以下将为您提供 C# 类的大小:
Marshal.SizeOf(typeof(Myclass));
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
class Myclass
{
}
Remember size of a class depends on padding.
请记住类的大小取决于填充。
回答by orellabac
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.
大多数已发布的解决方案都很棒并且工作正常,但它们的限制是您的类必须是可序列化的(有关更多详细信息,请参见:https: //docs.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;
}