如何配置protobuf-net typemodel以通过下面示例中的3个单元测试? Protobuf版本是v2 r470。
我已经简要地查看了svn树中的列表测试,但是没有发现它与protobuf-net svn中的null和empty测试之间的区别。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using ProtoBuf;
using ProtoBuf.Meta;
namespace ProtoCollections
{
[TestFixture]
public class CollectionTests
{
[Test]
public void TestEmptyList()
{
var model = TypeModel.Create();
var orig = new TypeWithReferenceList(Enumerable.Empty<SomeReferenceType>());
var clone = (TypeWithReferenceList)model.DeepClone(orig);
Assert.IsNotNull(clone.List);
Assert.IsEmpty(clone.List);
}
[Test]
public void TestNullList()
{
var model = TypeModel.Create();
var orig = new TypeWithReferenceList(null);
var clone = (TypeWithReferenceList)model.DeepClone(orig);
Assert.IsNull(clone.List);
}
[Test]
public void TestList()
{
var model = TypeModel.Create();
model[typeof (SomeReferenceType)].AsReferenceDefault = true;
SomeReferenceType repeatedItem = new SomeReferenceType(123);
var orig = new TypeWithReferenceList(new []{repeatedItem, repeatedItem});
var clone = (TypeWithReferenceList)model.DeepClone(orig);
Assert.AreEqual(orig.List.Count, clone.List.Count);
Assert.AreSame(orig.List[0], orig.List[1]);
Assert.AreEqual(orig.List[0].Value, clone.List[0].Value);
Assert.AreSame(clone.List[0], clone.List[1]);
}
}
[ProtoContract(ImplicitFields = ImplicitFields.AllFields, SkipConstructor = true)]
public class SomeReferenceType
{
private int value;
public SomeReferenceType(int val)
{
value = val;
}
public int Value { get { return value; } }
}
[ProtoContract(ImplicitFields = ImplicitFields.AllFields, SkipConstructor = true)]
public class TypeWithReferenceList
{
private List<SomeReferenceType> innerList;
public TypeWithReferenceList(IEnumerable<SomeReferenceType> items)
{
innerList = items == null ? null : items.ToList();
}
public List<SomeReferenceType> List { get { return innerList; } }
}
}
答案 0 :(得分:1)
第三个似乎是将AsReferenceDefault
应用于隐式字段的故障;看起来手动装饰成员(使用AsReference=true
)可以正常工作,就像在运行时应用它一样:
model[typeof(TypeWithReferenceList)][1].AsReference = true;
我会调查为什么会这样。
由于protobuf默认跳过空值的方式,第二个已经过了。
第一个更棘手 - 再次,因为谷歌规范没有null的概念,这是......有问题的。它目前可能被一些令人讨厌的虚假属性欺骗,但并不理想。就个人而言,我会说“保持简单;使集合始终为非null”(通常通过字段初始化程序或反序列化回调)。也可以扩展最近允许 列表中的空值的更改,以支持在列表外的显式空值(在选择加入的基础上)。
然而,这里的问题似乎是你希望它的行为类似于BinaryFormatter
。但是,不是 BinaryFormatter
。它不是作为BinaryFormatter
的替代品而设计的(虽然它可以很好地替换XmlSerializer
或DataContractSerializer
,它们具有更多相似的语义)。潜在的线路格式最终会受到限制 - 这是Google设计的有线和高效且无需行李的有线格式的体现。
特别是,在处理大多数DTO模型和目标场景时,大多数这些“限制”都不会出现。