C# ProtoBuf DeepClone在不使用代理时返回空对象

C# ProtoBuf DeepClone在不使用代理时返回空对象,c#,inheritance,serialization,protobuf-net,C#,Inheritance,Serialization,Protobuf Net,我使用的是protobuf net v2,有一个类继承了我不想序列化/克隆的“列表”。 当我调用“DeepClone”(或反序列化)时,我将克隆的对象设为空。 我可以将对象序列化到文件中,并且它似乎按照预期进行了序列化,但是RuntimeTypeModel无法从字节[]反序列化它 我发现解决这个问题的唯一方法是使用代理 如前所述,如果跳过“seturrogate”,则克隆失败。 有没有其他解决办法 附件: class Program { static void Main(string[]

我使用的是protobuf net v2,有一个类继承了我不想序列化/克隆的“列表”。
当我调用“DeepClone”(或反序列化)时,我将克隆的对象设为空。 我可以将对象序列化到文件中,并且它似乎按照预期进行了序列化,但是RuntimeTypeModel无法从字节[]反序列化它

我发现解决这个问题的唯一方法是使用代理

如前所述,如果跳过“seturrogate”,则克隆失败。 有没有其他解决办法

附件:

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; }
}
类程序
{
静态void Main(字符串[]参数)
{
RuntimeTypeModel模型=RuntimeTypeModel.Create();
模型[typeof(定制)].SetSurrogate(typeof(代理));
var original=新自定义{“C#”};
var clone=(自定义)model.DeepClone(原始);
Assert(clone.Count==original.Count);
}
}
[协议(IgnoreListHandling=true)]
公共类自定义:列表{}
[原始合同]
类代理
{
公共静态隐式运算符自定义(代理项代理项)
{
自定义原始=新自定义();
原件.AddRange(代理件);
归还原件;
}
公共静态隐式运算符代理(自定义原始)
{
return original==null?null:新的代理项{Pieces=original};
}
[原成员(1)]
内部列表项{get;set;}
}

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

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

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

这里的问题很简单,就是您通过以下方式显式地关闭了列表处理:

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

我放弃了对setUrrogate的调用,删除了IgnoreListHandling,克隆的对象为空。我错过了什么吗?@Tamir我有我目前的测试工具(通过了),你有什么不同的吗?我误解你的问题了吗?好的,现在可以了。但请告诉我,当我有一个像Custom一样继承List但包含其他成员的类型时,我应该忽略OreListHandling并使用代理?@Tamir与XmlSerializer和其他一些类型一样,通常是列表或数据实体。您可能会通过禁用列表处理来欺骗列表,但拥有一个
[ProtoMember(n)]私有IList InnerList{get{return this;}}
-有什么用处吗?是的,我考虑过这个选项,但我正在运行一个无法更改类型的系统。感谢您的回答,这非常有帮助。我取消了对setUrrogate的调用并删除了IgnoreListHandling,克隆的对象为空。我错过了什么吗?@Tamir我有我目前的测试工具(通过了),你有什么不同的吗?我误解你的问题了吗?好的,现在可以了。但请告诉我,当我有一个像Custom一样继承List但包含其他成员的类型时,我应该忽略OreListHandling并使用代理?@Tamir与XmlSerializer和其他一些类型一样,通常是列表或数据实体。您可能会通过禁用列表处理来欺骗列表,但拥有一个
[ProtoMember(n)]私有IList InnerList{get{return this;}}
-有什么用处吗?是的,我考虑过这个选项,但我正在运行一个无法更改类型的系统。谢谢你的回答,非常有帮助。
[TestFixture]
public class SO11034791
{
    [Test]
    public void Execute()
    {
        RuntimeTypeModel model = RuntimeTypeModel.Create();

        var original = new Custom<string> { "C#" };
        var clone = (Custom<string>)model.DeepClone(original);
        Assert.AreEqual(1, clone.Count);
        Assert.AreEqual("C#", clone.Single());
    }
    public class Custom<T> : List<T> { }
}