C# 对于复杂场景,引用跟踪失败

C# 对于复杂场景,引用跟踪失败,c#,.net,protobuf-net,C#,.net,Protobuf Net,使用R556,以下复杂场景的引用跟踪失败,请参阅测试中的断言。 对自定义集合使用垫片类而不是代理不会改变问题 显然,苏不喜欢我的描述,所以也许这篇无用的文章会让我的问题通过机器人的测试 using System.Collections.Generic; using System.IO; using Microsoft.VisualStudio.TestTools.UnitTesting; using ProtoBuf; using ProtoBuf.Meta; [TestClass] publ

使用R556,以下复杂场景的引用跟踪失败,请参阅测试中的断言。 对自定义集合使用垫片类而不是代理不会改变问题

显然,苏不喜欢我的描述,所以也许这篇无用的文章会让我的问题通过机器人的测试

using System.Collections.Generic;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ProtoBuf;
using ProtoBuf.Meta;

[TestClass]
public class UnitTest
{
    [ProtoContract]
    public class Whole
    {
        public Whole() { this.Parts = new PartCollection { Whole = this }; }
        [ProtoMember(1)]
        public readonly PartCollection Parts;
    }

    [ProtoContract]
    public class Part
    {
        [ProtoMember(1, AsReference = true)]
        public Whole Whole { get; set; }
    }

    public class PartCollection : List<Part>
    {
        public Whole Whole { get; set; }
    }

    [ProtoContract]
    public class Assemblage
    {
        [ProtoMember(1)]
        public readonly PartCollection Parts = new PartCollection();
    }

    [ProtoContract]
    public class PartCollectionSurrogate
    {
        [ProtoMember(1)]
        private PartCollection Collection { get; set; }

        [ProtoMember(2)]
        private Whole Whole { get; set; }

        public static implicit operator PartCollectionSurrogate(PartCollection value)
        {
            if (value == null) return null;
            return new PartCollectionSurrogate { Collection = value, Whole = value.Whole };
        }

        public static implicit operator PartCollection(PartCollectionSurrogate value)
        {
            if (value == null) return new PartCollection();
            value.Collection.Whole = value.Whole;
            return value.Collection;
        }
    }

    [TestMethod]
    public void TestMethod1()
    {
        RuntimeTypeModel.Default.Add(typeof(PartCollection), false).SetSurrogate(typeof(PartCollectionSurrogate));
        using (var stream = new MemoryStream())
        {
            {
                var whole = new Whole();
                var part = new Part { Whole = whole };
                whole.Parts.Add(part);
                var assemblage = new Assemblage();
                assemblage.Parts.Add(part);
                Serializer.Serialize(stream, assemblage);
            }

            stream.Position = 0;

            var obj = Serializer.Deserialize<Assemblage>(stream);
            {
                var assemblage = obj;
                var whole = assemblage.Parts[0].Whole;
                var referenceEqual = ReferenceEquals(assemblage.Parts[0], whole.Parts[0]);

                // The following assertion fails.
                Assert.IsTrue(referenceEqual);
            }
        }
    }
}
使用System.Collections.Generic;
使用System.IO;
使用Microsoft.VisualStudio.TestTools.UnitTesting;
使用ProtoBuf;
使用ProtoBuf.Meta;
[测试类]
公共类单元测试
{
[原始合同]
整个公共阶级
{
public整型(){this.Parts=new PartCollection{this};}
[原成员(1)]
公共只读部件集合部件;
}
[原始合同]
公共课部分
{
[原成员(1,AsReference=true)]
公共整整{get;set;}
}
公共类PartCollection:列表
{
公共整整{get;set;}
}
[原始合同]
公共类集合
{
[原成员(1)]
public readonly PartCollection Parts=new PartCollection();
}
[原始合同]
公共类PartCollectionSurrogate
{
[原成员(1)]
私有PartCollection集合{get;set;}
[原成员(2)]
私有整整{get;set;}
公共静态隐式运算符PartCollectionUrrogate(PartCollection值)
{
if(value==null)返回null;
返回新PartCollectionUrrogate{Collection=value,Whole=value.Whole};
}
公共静态隐式运算符PartCollection(PartCollectionSurrogate值)
{
if(value==null)返回新的PartCollection();
value.Collection.Whole=value.Whole;
返回值。集合;
}
}
[测试方法]
公共void TestMethod1()
{
RuntimeTypeModel.Default.Add(typeof(PartCollection),false).SetSurrogate(typeof(PartCollectionSurrogate));
使用(var stream=new MemoryStream())
{
{
var整=新整();
var part=新零件{整件=整件};
整体。部分。添加(部分);
var assemblage=新集合();
装配.零件.添加(零件);
序列化(流、汇编);
}
流位置=0;
var obj=序列化程序。反序列化(流);
{
var组合=obj;
var-total=assemblage.Parts[0].total;
var referenceEqual=ReferenceEquals(assembly.Parts[0],whole.Parts[0]);
//以下断言失败。
Assert.IsTrue(referenceEqual);
}
}
}
}
下面是使用shim类而不是代理的修复代码

using System.Collections.Generic;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ProtoBuf;

[TestClass]
public class UnitTest2
{
    [ProtoContract]
    public class Whole
    {
        public Whole() { this.Parts = new PartCollection { Whole = this }; }

        public PartCollection Parts;

        [ProtoMember(1)]
        public PartCollectionData PartsData
        {
            get { return PartCollectionData.ToData(Parts); }
            set { Parts = PartCollectionData.FromData(value); }
        }
    }

    [ProtoContract]
    public class Part
    {
        [ProtoMember(1, AsReference = true)]
        public Whole Whole { get; set; }
    }

    [ProtoContract(IgnoreListHandling = true)]
    public class PartCollection : List<Part>
    {
        public Whole Whole { get; set; }
    }

    [ProtoContract]
    public class Assemblage
    {
        public PartCollection Parts = new PartCollection();

        [ProtoMember(1)]
        public PartCollectionData PartsData
        {
            get { return PartCollectionData.ToData(Parts); }
            set { Parts = PartCollectionData.FromData(value); }
        }
    }

    [ProtoContract]
    public class PartCollectionData
    {
        [ProtoMember(1, AsReference = true)]
        public List<Part> Collection { get; set; }

        [ProtoMember(2, AsReference = true)]
        public Whole Whole { get; set; }

        public static PartCollectionData ToData(PartCollection value)
        {
            if (value == null) return null;
            return new PartCollectionData { Collection = value, Whole = value.Whole };
        }

        public static PartCollection FromData(PartCollectionData value)
        {
            if (value == null) return null;

            PartCollection result = new PartCollection { Whole = value.Whole };
            if (value.Collection != null)
                result.AddRange(value.Collection);
            return result;
        }
    }

    [TestMethod]
    public void TestMethod1()
    {
        using (var stream = new MemoryStream())
        {
            {
                var whole = new Whole();
                var part = new Part { Whole = whole };
                whole.Parts.Add(part);
                var assemblage = new Assemblage();
                assemblage.Parts.Add(part);
                Serializer.Serialize(stream, assemblage);
            }

            stream.Position = 0;

            var obj = Serializer.Deserialize<Assemblage>(stream);
            {
                var assemblage = obj;
                var whole = assemblage.Parts[0].Whole;
                Assert.AreSame(assemblage.Parts[0].Whole, whole.Parts[0].Whole, "Whole");
                Assert.AreSame(assemblage.Parts[0], whole.Parts[0], "Part");
            }
        }
    }
}
using System.Collections.Generic;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ProtoBuf;
using ProtoBuf.Meta;

[TestClass]
public class UnitTest
{
    [ProtoContract]
    public class Whole
    {
        public Whole() { this.Parts = new PartCollection { Whole = this }; }

        [ProtoMember(1)]
        public PartCollection Parts;
    }

    [ProtoContract]
    public class Part
    {
        [ProtoMember(1, AsReference = true)]
        public Whole Whole { get; set; }
    }

    [ProtoContract(IgnoreListHandling = true)]
    public class PartCollection : List<Part>
    {
        public Whole Whole { get; set; }
    }

    [ProtoContract]
    public class Assemblage
    {
        [ProtoMember(1)]
        public PartCollection Parts = new PartCollection();
    }

    [ProtoContract]
    public class PartCollectionSurrogate
    {
        [ProtoMember(1, AsReference = true)]
        public List<Part> Collection { get; set; }

        [ProtoMember(2, AsReference = true)]
        public Whole Whole { get; set; }

        public static implicit operator PartCollectionSurrogate(PartCollection value)
        {
            if (value == null) return null;
            return new PartCollectionSurrogate { Collection = value, Whole = value.Whole };
        }

        public static implicit operator PartCollection(PartCollectionSurrogate value)
        {
            if (value == null) return null;
            PartCollection result = new PartCollection { Whole = value.Whole };
            if (value.Collection != null)
                result.AddRange(value.Collection);
            return result;
        }
    }

    [TestMethod]
    public void TestMethod1()
    {
        RuntimeTypeModel.Default.Add(typeof(PartCollection), true).SetSurrogate(typeof(PartCollectionSurrogate));
        using (var stream = new MemoryStream())
        {
            {
                var whole = new Whole();
                var part = new Part { Whole = whole };
                whole.Parts.Add(part);
                var assemblage = new Assemblage();
                assemblage.Parts.Add(part);
                Serializer.Serialize(stream, assemblage);
            }

            stream.Position = 0;

            var obj = Serializer.Deserialize<Assemblage>(stream);
            {
                var assemblage = obj;
                var whole = assemblage.Parts[0].Whole;
                Assert.AreSame(assemblage.Parts[0].Whole, whole.Parts[0].Whole, "Whole");
                Assert.AreSame(assemblage.Parts[0], whole.Parts[0], "Part"); 
            }
        }
    }
}
使用System.Collections.Generic;
使用System.IO;
使用Microsoft.VisualStudio.TestTools.UnitTesting;
使用ProtoBuf;
[测试类]
公共类UnitTest2
{
[原始合同]
整个公共阶级
{
public整型(){this.Parts=new PartCollection{this};}
公共零件收集零件;
[原成员(1)]
公共部分收集数据部分数据
{
获取{return PartCollectionData.ToData(Parts);}
集合{Parts=PartCollectionData.FromData(值);}
}
}
[原始合同]
公共课部分
{
[原成员(1,AsReference=true)]
公共整整{get;set;}
}
[协议(IgnoreListHandling=true)]
公共类PartCollection:列表
{
公共整整{get;set;}
}
[原始合同]
公共类集合
{
public PartCollection Parts=new PartCollection();
[原成员(1)]
公共部分收集数据部分数据
{
获取{return PartCollectionData.ToData(Parts);}
集合{Parts=PartCollectionData.FromData(值);}
}
}
[原始合同]
公共类PartCollectionData
{
[原成员(1,AsReference=true)]
公共列表集合{get;set;}
[原成员(2,AsReference=true)]
公共整整{get;set;}
公共静态PartCollectionData ToData(PartCollection值)
{
if(value==null)返回null;
返回新的PartCollectionData{Collection=value,Whole=value.Whole};
}
公共静态PartCollection FromData(PartCollectionData值)
{
if(value==null)返回null;
PartCollection结果=新PartCollection{Whole=value.Whole};
if(value.Collection!=null)
result.AddRange(value.Collection);
返回结果;
}
}
[测试方法]
公共void TestMethod1()
{
使用(var stream=new MemoryStream())
{
{
var整=新整();
var part=新零件{整件=整件};
整体。部分。添加(部分);
var assemblage=新集合();
装配.零件.添加(零件);
序列化(流、汇编);
}
流位置=0;
var obj=序列化程序。反序列化(流);
{
var组合=obj;
var-total=assemblage.Parts[0].total;
Assert.arame(assemblage.Parts[0]。整,整。部分[0]。整,“整”);
Assert.arame(assemblage.Parts[0]、whole.Parts[0]、“Part”);
}
}
}
}
下面是固定的代理代码

using System.Collections.Generic;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ProtoBuf;

[TestClass]
public class UnitTest2
{
    [ProtoContract]
    public class Whole
    {
        public Whole() { this.Parts = new PartCollection { Whole = this }; }

        public PartCollection Parts;

        [ProtoMember(1)]
        public PartCollectionData PartsData
        {
            get { return PartCollectionData.ToData(Parts); }
            set { Parts = PartCollectionData.FromData(value); }
        }
    }

    [ProtoContract]
    public class Part
    {
        [ProtoMember(1, AsReference = true)]
        public Whole Whole { get; set; }
    }

    [ProtoContract(IgnoreListHandling = true)]
    public class PartCollection : List<Part>
    {
        public Whole Whole { get; set; }
    }

    [ProtoContract]
    public class Assemblage
    {
        public PartCollection Parts = new PartCollection();

        [ProtoMember(1)]
        public PartCollectionData PartsData
        {
            get { return PartCollectionData.ToData(Parts); }
            set { Parts = PartCollectionData.FromData(value); }
        }
    }

    [ProtoContract]
    public class PartCollectionData
    {
        [ProtoMember(1, AsReference = true)]
        public List<Part> Collection { get; set; }

        [ProtoMember(2, AsReference = true)]
        public Whole Whole { get; set; }

        public static PartCollectionData ToData(PartCollection value)
        {
            if (value == null) return null;
            return new PartCollectionData { Collection = value, Whole = value.Whole };
        }

        public static PartCollection FromData(PartCollectionData value)
        {
            if (value == null) return null;

            PartCollection result = new PartCollection { Whole = value.Whole };
            if (value.Collection != null)
                result.AddRange(value.Collection);
            return result;
        }
    }

    [TestMethod]
    public void TestMethod1()
    {
        using (var stream = new MemoryStream())
        {
            {
                var whole = new Whole();
                var part = new Part { Whole = whole };
                whole.Parts.Add(part);
                var assemblage = new Assemblage();
                assemblage.Parts.Add(part);
                Serializer.Serialize(stream, assemblage);
            }

            stream.Position = 0;

            var obj = Serializer.Deserialize<Assemblage>(stream);
            {
                var assemblage = obj;
                var whole = assemblage.Parts[0].Whole;
                Assert.AreSame(assemblage.Parts[0].Whole, whole.Parts[0].Whole, "Whole");
                Assert.AreSame(assemblage.Parts[0], whole.Parts[0], "Part");
            }
        }
    }
}
using System.Collections.Generic;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ProtoBuf;
using ProtoBuf.Meta;

[TestClass]
public class UnitTest
{
    [ProtoContract]
    public class Whole
    {
        public Whole() { this.Parts = new PartCollection { Whole = this }; }

        [ProtoMember(1)]
        public PartCollection Parts;
    }

    [ProtoContract]
    public class Part
    {
        [ProtoMember(1, AsReference = true)]
        public Whole Whole { get; set; }
    }

    [ProtoContract(IgnoreListHandling = true)]
    public class PartCollection : List<Part>
    {
        public Whole Whole { get; set; }
    }

    [ProtoContract]
    public class Assemblage
    {
        [ProtoMember(1)]
        public PartCollection Parts = new PartCollection();
    }

    [ProtoContract]
    public class PartCollectionSurrogate
    {
        [ProtoMember(1, AsReference = true)]
        public List<Part> Collection { get; set; }

        [ProtoMember(2, AsReference = true)]
        public Whole Whole { get; set; }

        public static implicit operator PartCollectionSurrogate(PartCollection value)
        {
            if (value == null) return null;
            return new PartCollectionSurrogate { Collection = value, Whole = value.Whole };
        }

        public static implicit operator PartCollection(PartCollectionSurrogate value)
        {
            if (value == null) return null;
            PartCollection result = new PartCollection { Whole = value.Whole };
            if (value.Collection != null)
                result.AddRange(value.Collection);
            return result;
        }
    }

    [TestMethod]
    public void TestMethod1()
    {
        RuntimeTypeModel.Default.Add(typeof(PartCollection), true).SetSurrogate(typeof(PartCollectionSurrogate));
        using (var stream = new MemoryStream())
        {
            {
                var whole = new Whole();
                var part = new Part { Whole = whole };
                whole.Parts.Add(part);
                var assemblage = new Assemblage();
                assemblage.Parts.Add(part);
                Serializer.Serialize(stream, assemblage);
            }

            stream.Position = 0;

            var obj = Serializer.Deserialize<Assemblage>(stream);
            {
                var assemblage = obj;
                var whole = assemblage.Parts[0].Whole;
                Assert.AreSame(assemblage.Parts[0].Whole, whole.Parts[0].Whole, "Whole");
                Assert.AreSame(assemblage.Parts[0], whole.Parts[0], "Part"); 
            }
        }
    }
}
使用System.Collections.Generic;
使用System.IO;
使用Microsoft.VisualStudio.TestTools.UnitTesting;
使用ProtoBuf;
使用ProtoBuf.Meta;
[测试类]
公共类单元测试
{
[原始合同]
整个公共阶级
{
Assert.AreSame(assemblage.Parts[0].Whole, whole.Parts[0].Whole, "Whole");
        [ProtoMember(1, AsReference = true)]
        private List<Part> Collection { get; set; }
Assert.AreSame(assemblage.Parts[0].Whole, whole.Parts[0].Whole, "Whole");
Assert.AreSame(assemblage.Parts[0], whole.Parts[0], "Part");