不使用代理时,ProtoBuf DeepClone返回空对象

时间:2012-06-14 14:02:18

标签: c# inheritance serialization protobuf-net

我正在使用protobuf-net v2并且有一个继承“List”的类,我不想序列化/克隆。
当我调用“DeepClone”(或反序列化)时,我将克隆的对象清空。 我可以将对象序列化为文件,它似乎按预期序列化,但RuntimeTypeModel不能从字节[]反序列化它。

我发现克服这个问题的单一解决方案是使用代理。

如上所述,如果您正在跳过“SetSurrogate”,则克隆失败。 还有其他选择来解决它吗?

附:

class Program
{
    static void Main(string[] args)
    {
        RuntimeTypeModel model = RuntimeTypeModel.Create();
        model[typeof(Custom<string>)].SetSurrogate(typeof(Surrogate<string>));

        var original = new Custom<string> { "C#" };
        var clone = (Custom<string>)model.DeepClone(original);
        Debug.Assert(clone.Count == original.Count);
    }
}

[ProtoContract(IgnoreListHandling = true)]
public class Custom<T> : List<T> { }

[ProtoContract]
class Surrogate<T>
{
    public static implicit operator Custom<T>(Surrogate<T> surrogate)
    {
        Custom<T> original = new Custom<T>();
        original.AddRange(surrogate.Pieces);
        return original;
    }

    public static implicit operator Surrogate<T>(Custom<T> original)
    {
        return original == null ? null : new Surrogate<T> { Pieces = original };
    }

    [ProtoMember(1)]
    internal List<T> Pieces { get; set; }
}

我发现的另一件事是当你用“System.Serializable”属性替换“Custom”类的ProtoContract属性时,即使没有代理,它也会按预期反序列化byte []。

1 个答案:

答案 0 :(得分:1)

这里的问题只是您显式关闭了列表处理,通过:

[ProtoContract(IgnoreListHandling = true)]
public class Custom<T> : List<T> { }

正如其名称所示,文档验证:

/// <summary>
/// If specified, do NOT treat this type as a list, even if it looks like one.
/// </summary>
public bool IgnoreListHandling {...}

所以:没有什么可用的,因为Custom<T>没有任何其他要序列化的数据成员。

所以:如果你没有使用代理,请不要禁用列表处理。此选项的主要目的是边缘情况,其中意图的某个东西是“对象”也具有使其看起来像一个列表的所有特征(所有protobuf-net需求是{{1和方便的IEnumerable[<T>]方法。)


Add(T)