Как получить размер байта типа в общем списке? - PullRequest
12 голосов
/ 31 августа 2011

У меня есть этот общий список, и я хочу получить размер байта типа, например, если T - строка или int и т. Д., Я пробовал оба способа, как написано в 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 ]

11 голосов
/ 31 августа 2011

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

Если вы действительно хотите узнать больше о размере, вот исчерпывающий ответ по теме.

10 голосов
/ 31 августа 2011

sizeof работает только для неуправляемых типов, таких как встроенные типы (int, float, char и т. Д.). Для ссылочных типов он просто возвращает размер указателя (обычно 4 для 32-битных систем) Он не будет работать вообще для ссылочных / управляемых типов (попробуйте и посмотрите).

Также вы не передаете ему тип, вы передаете ему объект типа Type.

Вы можете попробовать использовать Marshal.SizeOf, но я неУбедитесь, что это даст вам то, что вы хотите, для начала вам будет возвращен только размер типа после того, как он был упорядочен, а не размер, выделенный CLR.По следствию это также будет работать только с типами, которые можно маршалировать, списки которых не могут.

Что именно вы пытаетесь сделать?

6 голосов
/ 31 августа 2011

Вы можете использовать Marshal.SizeOf(typeof(T)), но имейте в виду, что он может генерировать типы с неизвестным размером.Помните, что Marshal.SizeoOf(typeof(char)) == 1.

...