我尝试使用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;
}
}
}
作为跟进(并澄清我的评论),请使用此代码:
使用System; 使用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");
}
}
}
答案 0 :(得分:2)
通过做:
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;
}
然后它会正常工作。