如何在通用列表中获取类型的字节大小?

15

我有一个通用列表,我想获得类型的字节大小,比如T是字符串或整数等。我尝试了getByteSize()中写的两种方法,并且只使用一种方法...

但是当我尝试编译时,它会出现错误,指出“错误:找不到'typeParameterType'的类型或命名空间名称(是否缺少using指令或程序集引用?)”

public class iList<T> : List<T> 
    { 
        public int getByteSize ()
        {
            // way 1
            Type typeParameterType = typeof(T);
            return sizeof(typeParameterType);

            // way 2
            Type typeParameterType = this.GetType().GetGenericArguments()[0];
            return sizeof(typeParameterType);
        }
    }

这里我做错了什么?
3个回答

12

sizeof只能用于值类型。

对于字符串,你只有在填充后才能知道实际的字节大小。

如果您坚持这样做,请序列化列表并测量它。虽然不是绝对可靠的方法,但可能比其他方法更好。 放弃吧,这样做没有什么用处,甚至需要付出额外的努力。您可以执行以下快速计数:

public int getListSize()
{
    Type type = typeof(T);

    if (type.IsEnum)
    {
        return this.Sum(item => Marshal.SizeOf(Enum.GetUnderlyingType(type)));
    }
    if (type.IsValueType)
    {
        return this.Sum(item => Marshal.SizeOf(item));
    }
    if (type == typeof(string))
    {
        return this.Sum(item => Encoding.Default.GetByteCount(item.ToString()));
    }
    return 32 * this.Count;
}

如果你真的想更多地了解大小,这里有一个关于该主题的全面的答案


1
Marshal.SizeOf(char) = 1!如果在.NET和“外部世界”之间进行数据交换以外的用途,这使得Marshal.SizeOf相当无用。 - xanatos
你说得没错,但是(我希望)不用说,如果这被用于在任何边界上传输数据,Char的大小不一致只是遇到的问题的一小部分。 - Paul Walls
sizeof 仅适用于 非托管 类型,这些类型仅是值类型的 _子集_(也包括不安全指针类型);例如,typeof(System.DateTime).IsValueTypetrue,但你不能使用它与 sizeofEncoding.Default 指的是 磁盘上 的默认字符编码(在 .NET 中为 ANSI,在 .NET Core 中为 UTF-8),而不是 内存中 的编码,后者始终为 UTF-16;因此,应该使用 item.ToString().Length * sizeof(char) - mklement0

10

sizeof只适用于非托管类型,如内置类型(intfloatchar等...)。对于引用/托管类型,它仅返回指针的大小(32位系统通常为4),根本不起作用(尝试一下就知道)。

此外,您传递给它的不是类型,而是 Type 类型的对象。

您可能想尝试使用Marshal.SizeOf,但我不确定这是否会给您想要的结果。首先,此函数仅在将类型编组后才返回其大小,而不是 CLR 分配的大小。反之,此函数仅适用于可编组的类型,列表则不行。

您究竟想做什么呢?


我正在尝试通过将列表中的总项目乘以项目类型的字节大小来确定列表的总大小... 如果我想使用sizeof(),该如何使用?还有一件事,它对于字符串类型会抛出异常。 - Safran Ali
2
在C#中,内存使用始终难以估计。只有内置类型和一些结构体(枚举类型、指针类型和不包含任何引用类型字段或属性的用户定义结构体)可以进行sizeof操作。其他对象是“不透明”的。 - xanatos

7

您可以使用Marshal.SizeOf(typeof(T)),但需要注意对于大小未知的类型可能会抛出异常。请注意Marshal.SizeoOf(typeof(char)) == 1


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接