不能序列化泛型类型
本文关键字:泛型类型 序列化 不能 | 更新日期: 2023-09-27 18:11:06
我试图用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;
}