Бывает необходимо сериализовать статический класс. Ниже приведена реализация расширения для бинарного сериализатора (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)); |
|
|