2010-04-06 60 views
1

我在系统中有DTO类的数量。它们被组织在继承层次结构中。将子类实例的基类部分与另一个基类实例进行比较

class Person 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string ListName { get; set; } 
} 

class PersonDetailed : Person 
{ 
    public string WorkPhone { get; set; } 
    public string HomePhone { get; set; } 
    public byte[] Image { get; set; } 
} 

将其拆分的原因是能够获得例如人的列表,搜索结果,而不必拖动沉重的图像和电话号码。然后在选择一个人的详细信息时加载完整的PersonDetail DTO。

我遇到的问题是在编写单元测试时比较这些。假设我有

Person p1 = myService.GetAPerson(); 
PersonDetailed p2 = myService.GetAPersonDetailed(); 

// How do I compare the base class part of p2 to p1? 
Assert.AreEqual(p1, p2); 

Assert上面会失败,因为p1p2属于不同类别。是否有可能以某种方式将p2的基类部分与p1进行比较?我是否应该在Person上实施IEquatable<>?其他建议?

回答

0

多一点调查(根据LBushkin的回答)让我改变主意。

Assert.Equals调用Equals方法来比较对象。在我的情况下,我可以在Person上创建一个覆盖,它将接受任何可以转换为Person的类型,然后比较所有属性。这将使我的原代码的工作:

Assert.AreEqual(p1, p2); 

我也必须重载equals我PersonExtended类检查存在的额外的字段。然而,将有“搞笑”的后果:

Assert.AreEqual(p1, p2); // calls p1.Equals(p2) - evaluates to true. 
Assert.AreEqual(p2, p1); // calls p2.Equals(p1) - evaluates to false. 

在这一点上,我决定建立一些更加简单 - 结果是对比较Person类型的扩展方法。这有一些优点:

  • 可以处理null左手参数。
  • 它是非虚拟的 - 很明显,变量的声明类型是使用的比较 。

现在看起来都很好,我可以继续编码。直到我发现在基本DAT和扩展DTO之间继承的整个想法是有缺陷的。我认为WCF使用的DataContractSerializer会将函数的参数声明为的类型序列化。它没有。它序列化对象的实际类型。这意味着如果一个PersonExtended对象被传递给一个只需要一个Person的方法,那么整个扩展方法就会通过电线传输,所以最好使用简单的组合。

2

我认为Assert.AreEqual对涉及的实例调用Equals方法。你应该能够简单地重写Equals逻辑,并检查在运行时,看看是否你是比较可能的情况之一:

  • 人< - >人员
  • 人< - > PersonDetailed
  • PersonDetailed < - >人员或
  • PersonDetailed < - > PersonDetailed

您可以将它们实现适当的逻辑对于每种情况,或者如您所认为的那样委托给外部比较器。我不知道如果微软公司以外的任何单元测试框架支持检查IEquatable<T>当你让他们验证平等。