Приближенный размер сериализуемого класса - PullRequest
1 голос
/ 31 августа 2010

Я хотел бы знать приблизительный сериализованный размер XML экземпляра класса, без фактической сериализации экземпляра. Конечно, я могу предоставить свойство, которое явно суммирует вместе размер всех полей, а также дополняет генерируемые теги XML. Тем не менее, (1) я хотел бы знать, если уже есть инструмент, который служит для этой цели - возможно, метод расширения, а если нет (2) я хотел бы знать, как сделать цикл, который использует отражение, чтобы приблизить размер ,

Прямо сейчас я делаю что-то вроде этого:

    private static readonly int averageTagSize = 20;

    [NonSerialized]
    public int EventSize
    {
        get
        {
            int size = 0;
            FieldInfo[] fields = this.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
            foreach (FieldInfo field in fields)
            {
                size += averageTagSize;
                switch (field.FieldType){
                    case typeof(int):
                        size += 32;
                        break;
                    case typeof(string):
                        string temp = field.GetValue(this) as string;
                        size += temp.Length;
                        break;
                        //...and so on
                }
            }
            return 0;
        }

    }

Приведенный выше код не работает, так как компилятор не позволяет мне включать информацию о типе. Предложения?

Ответы [ 3 ]

1 голос
/ 01 сентября 2010

Мой предыдущий пост ошибочен. Ответ, который я дал, работает в VB, но не в c #. Одним из способов решения этой проблемы было бы жестко закодировать имена типов следующим образом:

switch (field.FieldType.Name)
{
    case "Int32":
       size += 32;
       break;
    case "String":
       string temp = field.GetValue(this) as string;
       size += temp.Length;
       break;
}

Кроме того, вы можете использовать оператор if, чтобы избежать использования жестко закодированных строк:

foreach (FieldInfo field in fields)
{
    size += averageTagSize;
    if (field.FieldType.Name == typeof(int).Name)
    {
        size += 32;
    }
    else if (field.FieldType.Name == typeof(string).Name)
    {
        string temp = field.GetValue(this) as string;
        size += temp.Length;
    }
}
1 голос
/ 31 августа 2010

С сериализацией XML нет однозначного ответа, так как размер зависит от того, какие параметры XML Writer используются.Например, использование окончаний строк и отступов влияет на окончательный вывод файла.

Подход, который вы используете, может работать для приблизительной оценки.Однако вам также придется следить за любыми атрибутами, определенными в классах, свойствах и полях, которые могут контролировать, как именно сериализуется XML.

Что касается вашего оператора switch, то самая простая замена будетиспользовать if..else if..else блоков.

0 голосов
/ 31 августа 2010

Хотя существующие ответы о вашем подходе верны и дают лишь очень приблизительную оценку, я считаю, что ответом на ваш ближайший вопрос будет использование строкового имени типов.У меня нет доступа к компилятору ac # в моем доме, но я считаю, что это будет выглядеть примерно так:

switch (field.FieldType.Name){
                case typeof(int).ToString():
                     .....

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...