Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
99 / 99 / 33
Регистрация: 20.09.2014
Сообщений: 451
Записей в блоге: 3
1

Создание копии объекта через сериализацию

03.12.2015, 15:33. Показов 1783. Ответов 10
Метки нет (Все метки)

Всем доброго времени суток!
Реализую так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static T CopyFromSerialize<T>(T SerializableObject) where T : new()
        {
            try
            {
                MemoryStream stream = new MemoryStream();
 
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, SerializableObject);
                return (T)formatter.Deserialize(stream);
            }
            catch (Exception ex)
            {
                MessageSvc.ShowError(ex.Message);
                return new T();
            }
        }
Но когда доходит до десериализации выскакивает ошибка "конец потока обнаружен до завершения разбора".
Что я не так делаю?
Спасибо!
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.12.2015, 15:33
Ответы с готовыми решениями:

Создание полной копии объекта с рефлексией
Не знаю, будет ли кому-то интересно, все описал тут:...

Создание полной копии (deep copy) объекта
Всем привет, понадобилось в проекте создать полную копию объекта, для чего воспользовался...

Создание копии объекта используя объявление через указатель
Здравствуйте. Имеется такой код: #include &lt;iostream&gt; #include &lt;cstring&gt; using namespace std; ...

Сохранение данных через бинарную сериализацию
public class DataModel { public bool Active { get; set; } public int...

10
624 / 564 / 165
Регистрация: 17.07.2012
Сообщений: 1,604
Записей в блоге: 1
03.12.2015, 15:36 2
Лучший ответ Сообщение было отмечено OwenGlendower как решение

Решение

Serg34, после строчки с сериализацией
C#
1
stream.Seek(0, SeekOrigin.Begin);
1
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
03.12.2015, 19:51 3
Serg34, я вроде в блоге писал. Конечно, там решение можно доводить до ума и улучшать, но посыл верный:
https://www.cyberforum.ru/blog... g1518.html
1
99 / 99 / 33
Регистрация: 20.09.2014
Сообщений: 451
Записей в блоге: 3
04.12.2015, 10:30  [ТС] 4
Cupko, Спасибо. То, что было нужно!
Psilon, интересная статья. Тоже думал об этом, а тут готовое(или почти)) решение. Спасибо!
Только не совсем понял, копируются ли у Вас вложенные экземпляры классов?
0
Эксперт .NETАвтор FAQ
9856 / 4810 / 1731
Регистрация: 11.01.2015
Сообщений: 5,991
Записей в блоге: 34
04.12.2015, 11:14 5
Цитата Сообщение от Serg34 Посмотреть сообщение
C#
1
2
3
4
5
catch (Exception ex)
{
   //....
   return new T();
}
Вот этого не надо.
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
04.12.2015, 11:47 6
Serg34, ну должны копироваться
Правда там есть нюанс в интерфейсе ICloneable. То есть например массив классов фактически скопирует ссылки на старые объекты, а не сами объекты. Если это ненужное поведение (то есть нужна "глубокая" копия), то нужно эту ветку убрать.

Ну и нужно понимать, что тот код я писал больше 2 лет назад, за это время многое для меня поменялось
0
99 / 99 / 33
Регистрация: 20.09.2014
Сообщений: 451
Записей в блоге: 3
04.12.2015, 14:12  [ТС] 7
Storm23, согласен. Причем без блока try-catch эффект тот же -выводится на экран тоже сообщение (только без заголовка) и никаких исключений. Первый раз такое встречаю

Добавлено через 1 час 2 минуты
Цитата Сообщение от Psilon Посмотреть сообщение
должны копироваться
Не готов так сходу что-либо утверждать, но по моему "глубокая" копия в этом случае (если объект не сериализуемый) возможна только при помощи рекурсии, причем надо учитывать, что свойство может быть коллекцией, а коллекции аля Dictionary, - тоже нужно подумать как копировать и еще кучу всего надо учитывать. А чего еще придумают в будущем...
Вобщем, думаю для универсального решения проще все-таки пользоваться сериализацией.

Добавлено через 3 минуты
Цитата Сообщение от Psilon Посмотреть сообщение
код я писал больше 2 лет назад, за это время многое для меня поменялось
ок, я Вас не критикую, просто кодом интересуюсь
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
04.12.2015, 20:13 8
Serg34, так там и есть рекурсия

Цитата Сообщение от Serg34 Посмотреть сообщение
ок, я Вас не критикую, просто кодом интересуюсь
а это просто дисклеймер
0
99 / 99 / 33
Регистрация: 20.09.2014
Сообщений: 451
Записей в блоге: 3
06.12.2015, 22:10  [ТС] 9
Цитата Сообщение от Psilon Посмотреть сообщение
так там и есть рекурсия
Да, сразу не заметил (думал Clone - это из ICloneable)

А вот дисклеймер не зря давали:
1) код не дружит с null, но это решается просто.
2)А вот наследник словаря сбил код с толку посерьезнее: проверку на сериализируемость (ох как по-русски то звучит) он прошел, но как дошло до дела выдал сообщение, что сериализацию то он не поддерживает
(см. вложение)
0
Вложения
Тип файла: rar CheckClone.rar (56.4 Кб, 2 просмотров)
Эксперт .NETАвтор FAQ
9856 / 4810 / 1731
Регистрация: 11.01.2015
Сообщений: 5,991
Записей в блоге: 34
06.12.2015, 22:49 10
Psilon, Serg34,
Цитата Сообщение от Serg34 Посмотреть сообщение
А вот наследник словаря сбил код с толку посерьезнее: проверку на сериализируемость (ох как по-русски то звучит) он прошел, но как дошло до дела выдал сообщение, что сериализацию то он не поддерживает
В классе CloneSvc несколько ошибок:
1) BinaryFormatter требует атрибут Serializable. Даже если объект реализует ISerializable, все равно требуется атрибут. Поэтому для сериализации объектов, которые реализуют ISerializable, но не помечены как [Serializable] нужно сделать обертку с атрибутом, которую уже сериализовать.
2) В методе Clone: buffer = stream.GetBuffer(); => buffer = stream.ToArray();

Цитата Сообщение от Serg34 Посмотреть сообщение
А вот наследник словаря сбил код с толку
Если вы наследуете класс, которые реализует ISerializable (а Dictionary - именно такой), вам обязательно нужно создать специальный конструктор для ISerializable (это результат того, что в C# конструкторы не наследуются). В противном случае объект не сможет десериализоваться. Т.о. ваш класс MyDictionary должен выглядеть так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    [Serializable]
    public class MyDictionary : Dictionary<int, int>
    {
        public HasDictionary Object { get; set; }
 
        /// <summary>
        /// Default constructor
        /// </summary>
        public MyDictionary()
        {
        }
 
        /// <summary>
        /// ISerializable constructor
        /// </summary>
        protected MyDictionary(SerializationInfo info, StreamingContext context):base(info, context)
        {
        }
    }
1
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
06.12.2015, 23:41 11
Storm23, да там вообще много нужно менять (начать с того, что вместо 2 memorystream'ов нужно просто оффсет в 0 выставить при десериализации.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.12.2015, 23:41

Заказываю контрольные, курсовые, дипломные работы и диссертации здесь.

Создание объекта через корутину
Помогите вопрос решить такой: Есть корутина там создаются объекты, как то можно сделать так чтоб...

Ссылки и копии объекта
Я не могу до конца раза браться когда мы получаем ссылку на объект а когда его копию. Может я...

Создание объекта через IIS выдаёт ошибку
Создал asp страницу, всьо нормально работает но только я пытаюсь выполнить её ч-з IIS выдаёт ошибку...

Создание объекта через xml разметку. NullPointerExeption
Кажется у меня пробел в основах, я думал прописывая вью через разметку, при сборке создается...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.