Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
1

Изменение имени сериализуемого класса

18.04.2013, 15:16. Показов 3393. Ответов 11
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет.

В программе использую System.Xml.Serialization.XmlSerializer и в процессе разработки приходится заниматься рефакторингом: типа изменения имени класса. При этом в результат сериализации попадают имена классов, и если они были изменены, то десериализация не получится. Есть какие-то простые решения на этот счет?

Заранее спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.04.2013, 15:16
Ответы с готовыми решениями:

Clipboard копирование сериализуемого объекта
bool s = IsSerializable(this); DataFormats.Format format =...

Изменение имени ПК
Пытался сделать таким образом, но на Windows 7 не получил результата. Как возможно решить данный...

Изменение имени запускаемого процесса
Всем привет с# изменение имени запускаемого процесса как сделать помогите пожалуйста.

Вызов класса по его имени
Есть такая задача, из вне приходит строка которая равна имени класса, нужно как-то заставить...

11
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
18.04.2013, 19:56 2
Tulosba, несовсем понятно, что вам нужно. Если вы знаете какие объекты сохранены, то вы спокойной можете их десериализовать.Если не знаете, можно к каждому файлику прилагать небольшой манифест на 1-2килобайт, куда писать все, что вам нужно знать о классе.
0
Эксперт Java
4093 / 3827 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 11
18.04.2013, 21:16 3
Для xml-сериализатора вы можете добавить ко всем полям, которые переименованы, атрибуты с именами тегов.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
18.04.2013, 21:48  [ТС] 4
Допустим есть такой код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
 
namespace SerealizeExample
{
    [Serializable]
    public class SomeClass
    {
        public int SomeValue { get; set; }
    }
    class Program
    {
        static XmlSerializer serializer = new XmlSerializer(typeof(SomeClass));
 
        static void Main(string[] args)
        {
            SomeClass sc = new SomeClass();
            sc.SomeValue = 42;
 
            Console.WriteLine("'s' for Save, else - Load");
            if (Console.Read() == 's')
            {
                Save( sc );
            }
            else
            {
                Load( ref sc );
            }
 
            Console.WriteLine(sc.SomeValue);
            Console.ReadKey();
        }
 
        static void Load( ref SomeClass sc )
        {
            using( System.IO.FileStream fs = new System.IO.FileStream( "file.ser", System.IO.FileMode.Open ) )
            {
                sc = (SomeClass)serializer.Deserialize( fs );
            }
        }
        static void Save( SomeClass sc )
        {
            using( System.IO.FileStream fs = new System.IO.FileStream( "file.ser", System.IO.FileMode.Create ) )
            {
                serializer.Serialize(fs, sc);
            }
        }
    }
}
Можно сохранять, можно загружать. Всё вроде бы устраивает. Но если я через Refactor сделаю Rename класса SomeClass, то при загрузке вылетит исключение, т.к. сохранен другой класс (т.е. тот же, но под другим именем). Я хочу понять, можно как-то избежать исключительной ситуации после переименования класса.
0
Эксперт Java
4093 / 3827 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 11
19.04.2013, 07:22 5
C#
1
2
3
4
5
6
    [XmlRoot("RootElement")]
    [Serializable]
    public class SomeClass
    {
        public int SomeValue { get; set; }
    }
1
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
19.04.2013, 11:16 6
C#
1
        static void Load( ref SomeClass sc )
может все же

C#
1
        static SomeClass Load()
??
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
19.04.2013, 11:33  [ТС] 7
turbanoff, такой вариант работает. Однако, моя ситуация оказалась несколько иной. У меня коренной элемент должен быть списком объектов. Как быть в таком случае?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
 
namespace SerealizeExample
{
    [XmlRoot("RootElement")] // Не воспринимается в случае списка
    [Serializable]
    public class SomeClass
    {
        public int SomeValue { get; set; }
    }
 
    class Program
    {
        static XmlSerializer serializer = new XmlSerializer(typeof(List<SomeClass>));
 
        static void Main(string[] args)
        {
            List<SomeClass> list = new List<SomeClass>();
 
            SomeClass sc = new SomeClass();
            sc.SomeValue = 42;
 
            list.Add(sc);
 
            Console.WriteLine("'s' for Save, else - Load");
            if (Console.Read() == 's')
            {
                Save(list);
            }
            else
            {
                list.Clear();
                Load(ref list);
            }
 
            Console.WriteLine(sc.SomeValue);
            Console.ReadKey();
        }
 
        static void Load(ref List<SomeClass> list)
        {
            using (System.IO.FileStream fs = new System.IO.FileStream("file.ser", System.IO.FileMode.Open))
            {
                list = (List<SomeClass>)serializer.Deserialize(fs);
            }
        }
        static void Save(List<SomeClass> list)
        {
            using (System.IO.FileStream fs = new System.IO.FileStream("file.ser", System.IO.FileMode.Create))
            {
                serializer.Serialize(fs, list);
            }
        }
    }
}
Добавлено через 1 минуту
Psilon, я просто в качестве примера привел. Загрузка объектов - это уже другая тема.
0
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
19.04.2013, 11:50 8
Tulosba, просто методы load и save есть смысл вынести в сам класс...
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
19.04.2013, 12:06  [ТС] 9
Psilon, это поможет решению обозначенной проблемы ?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.04.2013, 12:10 10
Tulosba, я решал такую проблему агрегацией листа.
C#
1
2
3
4
5
6
[XmlRoot("RootElement")]
    public class RootSomeClass
    {
        [XmlArray("RootElements")]
        public List<SomeClass> Lst { get; set; }
    }
но мне это решение самому не нравится, а потому присоединяюсь к вашему вопросу, есть ли другие решения?

либо так
C#
1
2
3
4
5
6
[XmlRoot("RootElement")]
    public class RootSomeClass
    {
        [XmlElement("RootElements")]
        public List<SomeClass> Lst { get; set; }
    }
0
Master of Orion
Эксперт .NET
6100 / 4956 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
19.04.2013, 13:30 11
Tulosba, просто я не знаю ответа на ваш вопрос, поэтому подсказываю то, что знаю
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
19.04.2013, 14:34  [ТС] 12
Нашел в интернетах такое решение:
C#
1
static XmlSerializer serializer = new XmlSerializer(typeof(List<SomeClass>), new XmlRootAttribute("Something"));
Добавлено через 18 минут
Ну, и нужно еще
C#
1
[XmlType("NameInXml")]
добавить перед классом элемента списка.

Добавлено через 19 минут
Причем, по факту, даже XmlType будет достаточно для элемента. Имя тега для списка будет ArrayOf{XmlType}.
1
19.04.2013, 14:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.04.2013, 14:34
Помогаю со студенческими работами здесь

Получение имени класса-наследника
Есть базовый класс, в нём виртуальный метод принимающий некий параметр, у класса много наследников,...

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

Как создать объект по имени класса?
У меня имеется переменная в которой хранится имя класса, как мне по этой переменной создать объект...

перечислить найденные окна в процессе по имени класса, если их больше чем одно?
Подскажите пожалуйста как перечислить найденные окна в процессе по имени класса, если их больше чем...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru