以下场景似乎在反序列化中导致Protobuf.net中的异常.我做错了什么吗?这有什么方法吗? [ProtoContract][ProtoInclude(2, typeof(Ant))][ProtoInclude(3, typeof(Cat))]public interface IBeast{ [ProtoMember(1)] string
[ProtoContract] [ProtoInclude(2, typeof(Ant))] [ProtoInclude(3, typeof(Cat))] public interface IBeast { [ProtoMember(1)] string Name { get; set; } } [ProtoContract] public class Ant : IBeast { public string Name { get; set; } } [ProtoContract] public class Cat : IBeast { public string Name { get; set; } } [ProtoContract] [ProtoInclude(1, typeof(AntRule1))] [ProtoInclude(2, typeof(AntRule2))] [ProtoInclude(3, typeof(CatRule1))] [ProtoInclude(4, typeof(CatRule2))] public interface IRule<T> where T : IBeast { bool IsHappy(T beast); } [ProtoContract] public class AntRule1 : IRule<Ant> { public bool IsHappy(IAnt beast) { return true; } } [ProtoContract] public class AntRule2 : IRule<Ant> { public bool IsHappy(IAnt beast) { return true; } } [ProtoContract] public class CatRule1 : IRule<Cat> { public bool IsHappy(ICat beast) { return true; } } [ProtoContract] public class CatRule2 : IRule<Cat> { public bool IsHappy(ICat beast) { return true; } } public class TestSerialization { public void Serialize() { var antRules = new List<IRule<Ant>>(); antRules.Add(new AntRule1()); antRules.Add(new AntRule2()); var catRules = new List<IRule<Cat>>(); catRules.Add(new CatRule1()); catRules.Add(new CatRule2()); using (var fs = File.Create(@"c:\temp\antRules.bin")) { ProtoBuf.Serializer.Serialize(fs, antRules); fs.Close(); } using (var fs = File.OpenRead(@"c:\temp\antRules.bin")) { List<IRule<Ant>> list; list = ProtoBuf.Serializer.Deserialize<List<IRule<Ant>>>(fs); fs.Close(); } using (var fs = File.Create(@"c:\temp\catRules.bin")) { ProtoBuf.Serializer.Serialize(fs, catRules); fs.Close(); } using (var fs = File.OpenRead(@"c:\temp\catRules.bin")) { List<IRule<Cat>> list; list = ProtoBuf.Serializer.Deserialize<List<IRule<Cat>>>(fs); fs.Close(); } } }最后我怀疑这里的问题是:
[ProtoContract] [ProtoInclude(1, typeof(AntRule1))] [ProtoInclude(2, typeof(AntRule2))] [ProtoInclude(3, typeof(CatRule1))] [ProtoInclude(4, typeof(CatRule2))] public interface IRule<T> where T : IBeast
这表示对于任何T,IRule< T>.有4个孩子.这有副作用,如果你有一个以上的T,每个AndRule1 … CatRule2都有“n”个父母,这是不好的.让我们假设IRule< Ant>有2个蚂蚁规则,依此类推……(毕竟,我怀疑CatRule1是否真的是IRule< Ant>的实现).目前这只能通过RuntimeTypeModel表示,因为属性总是适用于所有T:
[ProtoContract] public interface IRule<T> where T : IBeast
和
// note these are unrelated networks, so we can use the same field-numbers RuntimeTypeModel.Default[typeof(IRule<Ant>)] .AddSubType(1, typeof(AntRule1)).AddSubType(2, typeof(AntRule2)); RuntimeTypeModel.Default[typeof(IRule<Cat>)] .AddSubType(1, typeof(CatRule1)).AddSubType(2, typeof(CatRule2));
然后它的工作原理.请注意,配置只需要执行一次,通常是在应用程序启动时.
考虑到这一点,我可能只是在运行时进行测试,并且在泛型的情况下简单地忽略任何不适用的 – 我的意思是在评估IRule< Dog>时,只考虑特定类型,如果它们实现IRule< Dog> .不过,我仍然有两种想法.