protobuf-net 存储结构化数据;object
本质上不是结构化的,它不会让您简单地为 声明子类object
,也不会让您对基本类型(如 )进行猴子string
,它具有非常特殊的序列化规则。
这在我的测试中效果很好
如果是这样,那就是一个错误;没有办法应该工作。完全没有。它当然不是受支持的方案,并且不能保证做正确的事情(它也可能严重破坏事情)。在这种情况下,我将更改代码以显式导致异常。我正在添加以下内容,以尽快修复:
嗯....我虽然这是一个无效的场景,但我的回归测试强调了一些“现有技术”,特别是:为什么在 protobuf-net 中序列化的字符串实习在这个例子中不起作用?
(这就是为什么每次我回答一个重要的 protobuf-net 问题时,我都会将其添加为回归测试,所以我没有撒谎)
我想我不应该排除它,但请想想小猫:这不是我推荐的做法。不过,我想我现在不能杀死它。但强调:我不能启用它来添加string
(等)作为子类型。仅考虑 API 消息类型,即您的自定义class
/ struct
s。
这样我就不必将类型信息嵌入到序列化消息中,因为对象类本身的反序列化很像 switch 语句
protobuf-net 通常也不嵌入类型信息;p 虽然有一些“动态”支持确实包含类型信息,但在这种情况下不需要它。
在不嵌入任何类型信息的情况下执行此操作的受支持方法是封装您想要的值,例如:
[TestFixture]
public class SO11641262
{
[Test]
public void Execute()
{
var model = TypeModel.Create();
model.Add(typeof (FooData), true)
.AddSubType(1, typeof (FooData<string>))
.AddSubType(2, typeof (FooData<int>))
.AddSubType(3, typeof (FooData<SomeOtherType>));
var val = FooData.Create("abc");
var clone = (FooData)model.DeepClone(val);
Assert.AreEqual("abc", clone.ValueUntyped);
Assert.AreEqual(typeof(string), clone.ItemType);
}
[ProtoContract]
public abstract class FooData
{
public static FooData<T> Create<T>(T value)
{
return new FooData<T> {Value = value};
}
public abstract Type ItemType { get; }
public abstract object ValueUntyped { get; set; }
}
[ProtoContract]
public class FooData<T> : FooData
{
[ProtoMember(1)]
public T Value { get; set; }
public override Type ItemType
{
get { return typeof (T); }
}
public override object ValueUntyped
{
get { return Value; }
set { Value = (T) value; }
}
}
[ProtoContract]
public class SomeOtherType {}
}