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

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

【问题讨论】:

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

标签: serialization protobuf-net


【解决方案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” - 它不存在今天;你要求澄清哪一部分,你想澄清什么
猜你喜欢
  • 1970-01-01
  • 2013-01-03
  • 1970-01-01
  • 1970-01-01
  • 2012-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多