MessagePack与UnitsNet序列化报错:Int64转Enum无效转换的解决方法
解决UnitsNet UnitInfo MessagePack反序列化InvalidCastException问题
问题核心
反序列化时抛出InvalidCastException: 无法将System.Int64转换为System.Enum,本质是MessagePack将枚举数值以Int64类型读取后,直接强转枚举类型失败——C#不支持数值类型到枚举的直接强制转换,必须通过枚举解析方法处理。
具体解决步骤
1. 重构自定义Formatter为泛型版本
针对泛型UnitInfo<TEnum>创建专属Formatter,确保序列化/反序列化时正确处理枚举类型:
public class UnitInfoFormatter<TEnum> : IMessagePackFormatter<UnitInfo<TEnum>> where TEnum : Enum { public void Serialize(ref MessagePackWriter writer, UnitInfo<TEnum> value, MessagePackSerializerOptions options) { // 将枚举转为Int64写入MessagePack流 var enumValue = (long)Convert.ChangeType(value.Unit, typeof(long)); writer.Write(enumValue); } public UnitInfo<TEnum> Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { // 读取Int64数值后,解析为目标枚举类型 long rawValue = reader.ReadInt64(); TEnum targetEnum = (TEnum)Enum.Parse(typeof(TEnum), rawValue.ToString()); return new UnitInfo<TEnum>(targetEnum); } }
2. 调整TestClass的Formatter绑定
在TestClass的属性上指定对应的泛型Formatter:
[MessagePackObject] public class TestClass { [Key(0), MessagePackFormatter(typeof(UnitInfoFormatter<LengthUnit>))] public UnitInfo<LengthUnit> MyProperty { get; set; } }
3. 正确注册CompositeResolver
确保泛型Formatter被纳入MessagePack的解析器链:
var customResolvers = new IMessagePackFormatter[] { new UnitInfoFormatter<LengthUnit>() }; var resolver = CompositeResolver.Create( customResolvers, StandardResolver.Instance ); var serializeOptions = MessagePackSerializerOptions.Standard.WithResolver(resolver);
4. 剥离无关配置
你提到的JsonSerializerSettings和UnitsNetIQuantityJsonConverter是JSON序列化的配置,和MessagePack无关,直接移除或隔离,避免干扰MessagePack的序列化逻辑。
内容的提问来源于stack exchange,提问作者habib salimi
相关产品推荐
相关产品推荐

