Форум программистов, компьютерный форум, киберфорум
Storm23
Войти
Регистрация
Восстановить пароль
Рейтинг: 5.00. Голосов: 1.

Сериализатор статических классов

Запись от Storm23 размещена 04.03.2017 в 02:02
Обновил(-а) Storm23 04.03.2017 в 02:27
Метки c#

Бывает необходимо сериализовать статический класс. Ниже приведена реализация расширения для бинарного сериализатора (BinaryFormatter), которая позволяет сериализовать и десериализовать статические классы или статические поля нестатических классов.

Расширение сериализует приватные и публичные статические поля и автоматические свойства, учитывает атрибут [NonSerialized], игнорирует поля типа Delegate и константы, корректно отрабатывает десериализацию когда поле уже не существует в классе.

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
    public static class StaticSerializerExtension
    {
        public static void SerializeStatic(this BinaryFormatter formatter, Stream stream, Type type)
        {
            var fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            var arr = new List<object>();
            foreach (var field in fields)
            {
                var nonSerialized = field.GetCustomAttributes(typeof(NonSerializedAttribute), true);
                if (nonSerialized.Length > 0) continue;//field is not serialized
                if (field.FieldType.IsSubclassOf(typeof (Delegate))) continue;//do not serialize delegates
                if (field.IsLiteral) continue;//do not serialize constants
                arr.Add(field.Name);
                arr.Add(field.GetValue(null));
            }
            formatter.Serialize(stream, arr);
        }
 
        public static void DeserializeStatic(this BinaryFormatter formatter, Stream stream, Type type)
        {
            var arr = (List<object>)formatter.Deserialize(stream);
 
            for (int i = 0; i < arr.Count; i += 2)
            {
                var name = (string)arr[i];
                var val = arr[i + 1];
                var field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                if (field == null) continue;//field is not exists
                var nonSerialized = field.GetCustomAttributes(typeof(NonSerializedAttribute), true);
                if (nonSerialized.Length > 0) continue;//field is not serialized
                field.SetValue(null, val);
            }
        }
    }
Пример использования:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    public static class SomeStaticClass
    {
        public static string A;
        private static float B;
        public static int C { get; set; }
        [NonSerialized]
        public static string D;
    }
 
    ...
 
    //сериализуем статический класс SomeStaticClass
    using (var fs = new FileStream(fileName, FileMode.Create))
        new BinaryFormatter().SerializeStatic(fs, typeof(SomeStaticClass));
 
    //десериализуем статический класс SomeStaticClass
    using (var fs = new FileStream(fileName, FileMode.Open))
        new BinaryFormatter().DeserializeStatic(fs, typeof(SomeStaticClass));
Размещено в C#, WinForms
Показов 2634 Комментарии 0
Всего комментариев 0
Комментарии
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru