gpt4 book ai didi

Protobuf-net 序列化错误 = "The type cannot be changed once a serializer has been generated"

转载 作者:行者123 更新时间:2023-12-01 02:44:13 26 4
gpt4 key购买 nike

以下场景似乎会导致 Protobuf.net 中的反序列化异常。我做错了什么吗?有没有办法解决这个问题?

[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个 child 。如果您有多个 T,这会产生副作用。 ,各 AndRule1 ... CatRule2每个人都有“n”个 parent ,这不好。让我们假设 IRule<Ant>有 2 条 Ant 规则,依此类推......(毕竟,我怀疑 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> .不过,我仍然有两种想法。

关于Protobuf-net 序列化错误 = "The type cannot be changed once a serializer has been generated",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7333233/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com