【发布时间】:2017-07-17 11:54:28
【问题描述】:
我有一个小单元测试来测试循环依赖。
我的对象如下:
[ProtoContract]
public class Node
{
[ProtoMember(1)]
public String Name { get; set; }
[ProtoMember(2,AsReference = true)]
public List<Node> Childs { get; set; }
public Node()
{
Childs = new List<Node>();
}
}
还有以下服务:
[ServiceContract]
public interface INodeService : IService
{
[OperationContract]
Task<Node> GetCyclicNodes();
}
public class NodeService : Service, INodeService
{
public async Task<int> Add(int a, int b)
{
return a + b;
}
public async Task<Node> GetCyclicNodes()
{
Node nodeA = new Node() {Name = "Node A"};
Node nodeB = new Node() {Name = "Node B"};
Node nodeC = new Node() {Name = "Node C"};
nodeA.Childs.Add(nodeB);
nodeB.Childs.Add(nodeC);
nodeC.Childs.Add(nodeA);
return nodeA;
}
}
在客户端我计算对象的数量:
private int CountNodes(Node node, List<Node> countedNodes = null)
{
if (countedNodes == null)
{
countedNodes = new List<Node>();
}
if (countedNodes.Contains(node))
{
return 0;
}
else
{
countedNodes.Add(node);
int count = 1;
foreach (Node nodeChild in node.Childs)
{
count += CountNodes(nodeChild, countedNodes);
}
return count;
}
}
当我调用它时,我希望收到整个层次结构,其中包含 3 个唯一对象实例(一个用于“节点 A”、“节点 B”、“节点 C”)。
但似乎我有 4 个不同的对象,是对象 A 的两倍。
由于我的班级不是AsReferenceDefault,我有点担心它看不出它与它得到的对象不是同一个对象。
就我而言,我有一个非常大的商业模式(约 500 种不同的模式),它们都继承自同一个根类。每个类都可以在技术上(从模型的角度)被另一个引用,很明显每个类都是唯一的所有者,而其他的只是引用它。 这是我可以用 protobuf 做的事情吗?
因为即使我不知道使用引用时幕后发生了什么,我也有点担心这意味着每个字段都放置了一个唯一的 ID,即使它们没有被引用
编辑
事实上,即使在ProtoContract 上设置AsReferenceDefault = true,我仍然得到4 个对象而不是3 个,现在我有点迷失了。
编辑 2
我确实做了另一个测试,我尝试了一个 Container 类(我的不同操作现在返回一些 Task<Container<Node>>。这个 Container 只包含一个标记为 AsReference = true 的属性。现在它可以工作了,我只有 3实例。
但似乎暗示我没有正确理解AsReference 机制。我在想可能有一个对象的“所有者”,它没有用AsReference=true 标记,所有其他也引用这个对象的对象都是AsReference =true。但如果我理解正确,这将导致有 2 个不同的实例?
如果是,我不明白设置AsReference = true 相对于AsReferenceDefault 的优势?
我理解正确吗?
【问题讨论】:
-
@MarcGravell 你有没有机会检查这个错误。我们还有很多其他情况,设置
AsReferenceDefault=true是不够的。
标签: wcf protocol-buffers protobuf-net