我正在尝试使用protobuf-net序列化通用类型,但是protobuf-net表示无法序列化它。
如:
RuntimeTypeModel.Default.CanSerialize(typeof(MyGenericClass<>))
返回true和
RuntimeTypeModel.Default.CanSerialize(typeof(string))
也返回true。但
RuntimeTypeModel.Default.CanSerialize(typeof(MyGenericClass<string>)) //--> applies to all types that would return true when directly serialized as shown above for the string type
返回false。我猜我在将我添加MyGenericClass
到默认运行时类型模型时做错了。由于类似
RuntimeTypeModel.Default.CanSerialize(typeof(List<Document>))
返回true。
我当前添加通用类的代码:
var addedGenericType = RuntimeTypeModel.Default.Add(typeof(MyGenericClass<>), false);
addedGenericType.Add("Field1", "GenericField");
错误消息说我要序列化的类型没有合同...这显然是不正确的。
这是一个演示我的问题并证明它应该起作用的示例:
using System;
using ProtoBuf;
namespace TestApplication
{
[ProtoContract]
public class TestClass<T>
{
[ProtoMember(1, DynamicType = true)]
public T TestField { get; set; }
}
public class TestClass2<T>
{
public T TestField { get; set; }
}
public class Tester
{
public void Test()
{
DefineSecondClass();
bool testResult = ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(typeof(TestClass<string>));
bool testResult2 = ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(typeof(TestClass2<string>));
bool testResult3 = ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(typeof(TestClass2<>));
Console.WriteLine(testResult); // returns true
Console.WriteLine(testResult2); // returns false
Console.WriteLine(testResult3); // returns true
}
private void DefineSecondClass()
{
var type = ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(TestClass2<>), false);
type.AddField(1, "TestField");
type[1].DynamicType = true;
}
}
}
作为后续步骤(并澄清我的意见),让我们采用以下代码:
使用系统;使用ProtoBuf;
namespace TestApplication
{
public class TestClass<T>
{
public T TestField { get; set; }
}
public class ComplexType
{
public string SomeFieldA{get; set;}
public int SomeFieldB{get; set;}
}
public class Tester
{
public void Test()
{
DefineComplexType();
// how to add the type TestClass<ComplexType> to the RuntimeTypeModel without calling
// DefineComplexType() again?
}
private void DefineComplexType()
{
var type = ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(ComplexType), false);
type.AddField(1, "SomeFieldA");
}
}
}
通过做:
var type = ProtoBuf.Meta.RuntimeTypeModel.Default.Add(
typeof(TestClass2<>), false);
type.AddField(1, "TestField");
type[1].DynamicType = true;
您已经配置了TestClass2<>
类型。很棒,但是...您永远不要使用该类型。实际上,它不能使用-Add
应该抛出一个错误。您TestClass<string>
在大多数意图和目的中使用的是一个完全独立的Type
实例。
我猜这里的逻辑是:如果配置了通用类型定义,则封闭的通用类型应该从通用类型定义继承其配置。我可以看到它的逻辑,但是:目前还没有实现,就像其他所有东西一样,需要规范,设计,实现,测试,支持和文档。这需要时间。
对于今天:如果要使用TestClass2<string>
,应配置 TestClass2<string>
。
请注意,使用属性时,属性固有地存在于封闭类型上;因此TestClass1<string>.TestField
带有[ProtoMember(1, DynamicType = true)]
标记的情况就是如此。
我怀疑如果您这样做:
private void DefineSecondClass()
{
var type = ProtoBuf.Meta.RuntimeTypeModel.Default.Add(
typeof(TestClass2<string>), false);
type.AddField(1, "TestField");
type[1].DynamicType = true;
}
那就可以了
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句