how to get byte size of type in generic list?
Asked Answered
I

3

15

I have this generic list and I want to get the byte size of the type like if T is string or int etc., I tried both ways as written in getByteSize(), and just to let you know I am using only one way at a time ...

but when I try to compile, it gives an error saying "Error: The type or namespace name 'typeParameterType' could not be found (are you missing a using directive or an assembly reference?)"

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

And idea what I am doing wrong here?

Iyar answered 31/8, 2011 at 10:56 Comment(0)
D
12

sizeof is only going to work on value types.

For a string, you won't know the actual byte size until you populate it.

If you are set on doing this, serialize the list and measure it then. While not a guaranteed way, it is probably better than the alternative. Scratch that. It won't get you what you want without some real effort, if at all. You could perform a quick and dirty count like so:

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

If you really want to know more about size, here is a comprehensive answer on the topic.

Deserted answered 31/8, 2011 at 11:35 Comment(3)
Marshal.SizeOf(char) = 1! This makes the Marshal.SizeOf quite useless if used outside of marshaling data between .NET and "outside world".Did
You are correct, but (I hope) it goes without saying that the size inconsistencies of Char are only a small part of the problems that would be encountered if this was being used to push data across any sort of boundary.Deserted
sizeof only works on unmanaged types, which are only a subset of value types (and also include unsafe pointer types); e.g., typeof(System.DateTime).IsValueType is true, but you can't use it with sizeof. Encoding.Default refers to the on-disk default character encoding (ANSI in .NET, UTF-8 in .NET Core), not the in-memory encoding, which is always UTF-16; thus, item.ToString().Length * sizeof(char) should be used.Countermeasure
M
10

sizeof only works for unmanaged types, such as built in types (int, float, char etc...). For reference types it simply returns the size of a pointer (normally 4 for 32 bit systems) It won't work at all for reference / managed types (try it and see).

Also you aren't passing it a type, you are passing it an object of type Type.

You might want to try using Marshal.SizeOf instead, however I'm not sure this will give you what you want, to start with this will only return the size of the type after it has been marshalled, not the size allocated by the CLR. By corollary this will also only work with types that can be marshalled, of which lists cannot.

What exactly is it that you are trying to do?

Musjid answered 31/8, 2011 at 11:4 Comment(2)
i am trying to find out the total size of list by using total item in the list multiply by bytesize of item's type ... if i want to use sizeof() how can i use it? and one more thing it is throwing exception for string typeIyar
@S Memory use in C# is always difficult to estimate. Only built-in types and some structs (Enum types, Pointer types and User-defined structs that do not contain any fields or properties that are reference types) can be sizeoffed. Other objects are "opaque".Did
D
8

You can use Marshal.SizeOf(typeof(T)) but be aware that it can throw for types with unknown size. Be aware that Marshal.SizeoOf(typeof(char)) == 1.

Did answered 31/8, 2011 at 11:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.