仅在 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.INHibernateProxy
、NHibernate.Proxy.DynamicProxy.IProxy
或 NHibernate.Intercept.IFieldInterceptorAccessor
我愿意讨论可以添加的新添加以放松这一点 - 可能需要进行一些讨论,但是:应该是可能的。简单地添加一个标记接口或库识别为“忽略此类型”标记的属性似乎很合理!事实上,正如我所想:似乎我们可以为此使用[ProtoIgnore]
,通过扩展AttributeTargets
为ProtoContractAttribute
,并在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 RuntimeTypeModel 不序列化基类的成员