仅在 ProtoBuf-net 中序列化基类

Posted

技术标签:

【中文标题】仅在 ProtoBuf-net 中序列化基类【英文标题】:Serialize base class only in ProtoBuf-net 【发布时间】:2020-06-11 09:05:44 【问题描述】:

我们有一个基类和派生类。当我们序列化派生类时,我们只想序列化基类。我们如何在 ProtoBuf-net 中实现这一点。

【问题讨论】:

我需要更多上下文:派生类对 protobuf-net 是否“已知”,而您只想忽略它?还是protobuf-net不知道并且永远不会知道的不相关的实现细节?或者...?也许是一个代码示例? protobuf-net v3 在这里获得了一个新选项;见编辑 【参考方案1】:

编辑:v3 中的新内容;以下现在有效:

[ProtoContract(IgnoreUnknownSubTypes = true)]
public class Foo 

这正是你想要的。


目前 protobuf-net 对意外类型不太宽容,因为它真的希望能够往返您的数据。在 3.0 代码库中,目前仅限于:

EF 代理,它通过命名空间System.Data.Entity.DynamicProxies 检测到 NHibernate 代理,它检测为任何实现按名称 NHibernate.Proxy.INHibernateProxyNHibernate.Proxy.DynamicProxy.IProxyNHibernate.Intercept.IFieldInterceptorAccessor

我愿意讨论可以添加的新添加以放松这一点 - 可能需要进行一些讨论,但是:应该是可能的。简单地添加一个标记接口或库识别为“忽略此类型”标记的属性似乎很合理!事实上,正如我所想:似乎我们可以为此使用[ProtoIgnore],通过扩展AttributeTargetsProtoContractAttribute,并在DynamicStub.ResolveProxies 中添加几行。

现在,以下“作品”(对于“作品”的有限值),带有输出:

Trying BaseType...
Success; got BaseType
Trying KnownSubTypeViaInclude...
Success; got KnownSubTypeViaInclude
Trying UnknownSubType...
Unexpected sub-type: UnknownSubType
Trying LooksLikeEFProxy...
Success; got BaseType
Trying LooksLikeNHibernateProxy...
Success; got BaseType

代码:

using ProtoBuf;
using System;

static class P

    static void Main()
    
        // works, trivially
        Try<BaseType>();

        // works, processes sub-type
        Try<KnownSubTypeViaInclude>(); 

        // fails, unexpected
        Try<UnknownSubType>();

        // works, processes base type only
        Try<System.Data.Entity.DynamicProxies.LooksLikeEFProxy>();
        Try<LooksLikeNHibernateProxy>();
    
    static void Try<T>() where T : BaseType, new()
    
        Console.WriteLine($"Trying typeof(T).Name...");
        try
        
            var clone = Serializer.DeepClone<BaseType>(new T());
            Console.WriteLine($"Success; got clone.GetType().Name");
        
        catch (Exception ex)
        
            Console.WriteLine(ex.Message);
        
    


[ProtoContract]
[ProtoInclude(42, typeof(KnownSubTypeViaInclude))]
public class BaseType



public class KnownSubTypeViaInclude : BaseType  
public class UnknownSubType : BaseType  
public class LooksLikeNHibernateProxy : BaseType, NHibernate.Proxy.INHibernateProxy  
namespace System.Data.Entity.DynamicProxies

    public class LooksLikeEFProxy : BaseType  

namespace NHibernate.Proxy // let's pretent to be NHibernate

    public interface INHibernateProxy  

【讨论】:

我们的情况是,我们有一个可以用 protobuf-net 序列化的类 A 和一个从 A 继承但没有任何 protobuf-met 注释的类 B,因此不可序列化。但是我们有这样的情况,我们确实有一个包含 A 类和 B 类对象的集合,并且这个集合应该被序列化。显然 B 不能被序列化,但它的基 A 可以。所以理想情况下,我们可以以某种方式标记 A 类,以便应该序列化 B 类的序列化程序知道,它必须序列化为 A 类。也许现在这是可能的,但我不知道。 知道如何使用 protobuf-net 解决我们的问题吗? @ChristianBecker 我在答案中解释了所有这些...... a)您所要求的内容不受直接支持(我解释了原因),b)我给出了一些 使它 工作的技巧,并且 c) 我推测我愿意添加 更直接的支持,但又一次 - 参见“a” - 它不存在今天;你要求澄清哪一部分,你想澄清什么

以上是关于仅在 ProtoBuf-net 中序列化基类的主要内容,如果未能解决你的问题,请参考以下文章

Protobuf-net 包括不可序列化基类的特定成员

Protobuf-net RuntimeTypeModel 不序列化基类的成员

Protobuf-net 创建具有接口和抽象基类的类型模型

限制 protobuf-net 继承“树”

如何停止使用 Protobuf-Net 继承,直接使用继承类?

在 protobuf-net 中序列化 IEnumerable