不能序列化泛型类型

本文关键字:泛型类型 序列化 不能 | 更新日期: 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;
}