替代BinaryFormatter实现Hashtable的序列化与反序列化方案
嵌套Hashtable序列化替代方案(替代BinaryFormatter)
以下几种方案可完整保留Hashtable的嵌套层级结构,替代已废弃的BinaryFormatter:
1. NetDataContractSerializer(官方自带,无需额外依赖)
该组件属于.NET框架原生,与BinaryFormatter逻辑类似,保留完整类型元数据,可完美处理嵌套Hashtable:
using System.IO; using System.Runtime.Serialization; using System.Collections; // 序列化方法 public static byte[] SerializeHashtable(Hashtable hashtable) { using (var ms = new MemoryStream()) { var serializer = new NetDataContractSerializer(); serializer.Serialize(ms, hashtable); return ms.ToArray(); } } // 反序列化方法 public static Hashtable DeserializeHashtable(byte[] serializedData) { using (var ms = new MemoryStream(serializedData)) { var serializer = new NetDataContractSerializer(); return (Hashtable)serializer.Deserialize(ms); } }
优势:无需引入第三方包,类型信息保留完整,反序列化直接还原嵌套结构。
2. Newtonsoft.Json 自定义转换器
System.Text.Json默认会将Hashtable转为Dictionary导致嵌套结构丢失,使用Newtonsoft.Json配合自定义转换器可解决该问题:
首先安装Newtonsoft.Json NuGet包,然后实现转换器:
using Newtonsoft.Json; using System.Collections; public class HashtableConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(Hashtable); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var hashtable = new Hashtable(); if (reader.TokenType == JsonToken.StartObject) { while (reader.Read() && reader.TokenType != JsonToken.EndObject) { var key = reader.Value; reader.Read(); var value = serializer.Deserialize(reader); // 递归将嵌套Dictionary转回Hashtable if (value is Dictionary<string, object> dict) { value = ConvertDictToHashtable(dict); } hashtable.Add(key, value); } } return hashtable; } private Hashtable ConvertDictToHashtable(Dictionary<string, object> dict) { var hashtable = new Hashtable(); foreach (var kvp in dict) { hashtable.Add(kvp.Key, kvp.Value is Dictionary<string, object> nestedDict ? ConvertDictToHashtable(nestedDict) : kvp.Value); } return hashtable; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var hashtable = (Hashtable)value; writer.WriteStartObject(); foreach (DictionaryEntry entry in hashtable) { writer.WritePropertyName(entry.Key.ToString()); serializer.Serialize(writer, entry.Value); } writer.WriteEndObject(); } }
使用示例:
// 序列化 var jsonSettings = new JsonSerializerSettings { Converters = new List<JsonConverter> { new HashtableConverter() } }; string json = JsonConvert.SerializeObject(yourHashtable, jsonSettings); // 反序列化 Hashtable restoredHashtable = JsonConvert.DeserializeObject<Hashtable>(json, jsonSettings);
优势:JSON格式可读性强,自定义逻辑灵活,支持复杂嵌套结构。
3. MessagePack-CSharp 自定义格式化器
若需二进制序列化的高性能,可使用MessagePack配合自定义格式化器处理Hashtable:
首先安装MessagePack NuGet包,实现自定义格式化器:
using MessagePack; using System.Collections; public class HashtableFormatter : IMessagePackFormatter<Hashtable> { public void Serialize(ref MessagePackWriter writer, Hashtable value, MessagePackSerializerOptions options) { writer.WriteMapHeader(value.Count); foreach (DictionaryEntry entry in value) { options.Resolver.GetFormatterWithVerify<object>().Serialize(ref writer, entry.Key, options); options.Resolver.GetFormatterWithVerify<object>().Serialize(ref writer, entry.Value, options); } } public Hashtable Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { int count = reader.ReadMapHeader(); var hashtable = new Hashtable(count); for (int i = 0; i < count; i++) { var key = options.Resolver.GetFormatterWithVerify<object>().Deserialize(ref reader, options); var value = options.Resolver.GetFormatterWithVerify<object>().Deserialize(ref reader, options); // 递归转换嵌套Dictionary为Hashtable if (value is Dictionary<object, object> dict) { value = ConvertDictToHashtable(dict); } hashtable.Add(key, value); } return hashtable; } private Hashtable ConvertDictToHashtable(Dictionary<object, object> dict) { var hashtable = new Hashtable(); foreach (var kvp in dict) { hashtable.Add(kvp.Key, kvp.Value is Dictionary<object, object> nestedDict ? ConvertDictToHashtable(nestedDict) : kvp.Value); } return hashtable; } }
注册并使用:
var msgPackOptions = MessagePackSerializerOptions.Standard.WithResolver(new CompositeResolver( new[] { new HashtableFormatter() }, new[] { StandardResolver.Instance })); // 序列化 byte[] msgPackData = MessagePackSerializer.Serialize(yourHashtable, msgPackOptions); // 反序列化 Hashtable restoredHashtable = MessagePackSerializer.Deserialize<Hashtable>(msgPackData, msgPackOptions);
优势:二进制格式体积小、序列化速度快,适合高性能场景。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

