Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将子类实例的基类部分与另一个基类实例进行比较_C# - Fatal编程技术网

C# 将子类实例的基类部分与另一个基类实例进行比较

C# 将子类实例的基类部分与另一个基类实例进行比较,c#,C#,我在一个系统中有很多类。它们被组织在继承层次结构中 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

我在一个系统中有很多类。它们被组织在继承层次结构中

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);

上面的断言将失败,因为p1和p2是不同的类。是否可以只比较
p2
p1
的基类部分?我应该在
Person
上实现
IEquatable
?其他建议?

我相信,
Assert.AreEqual
会对所涉及的实例调用
Equals
方法。您应该能够简单地重写Equals逻辑,并在运行时检查是否正在比较以下一种可能的情况:

  • 个人
  • 被跟踪的人
  • 有人跟踪的人或
  • 直截了当的直截了当的
您可以为每种情况实现适当的逻辑,或者根据需要委托给外部比较器。我不知道微软以外的单元测试框架是否支持在你要求他们验证平等性时检查
IEquatable

更多的调查(基于LBushkin的回答)让我改变了主意

Assert.Equals
调用
Equals
方法来比较对象。在我的例子中,我可以在
Person
上创建一个覆盖,该覆盖将接受可以强制转换为
Person
的任何类型,然后比较所有属性。这将使我的原始代码正常工作:

Assert.AreEqual(p1, p2);
我还必须在我的
PersonExtended
类中重写Equals,以检查存在的额外字段。然而,这将产生“有趣”的后果:

Assert.AreEqual(p1, p2); // calls p1.Equals(p2) - evaluates to true.
Assert.AreEqual(p2, p1); // calls p2.Equals(p1) - evaluates to false.
在这一点上,我决定构建更简单的东西-结果是在比较的
Person
类型上的扩展方法。这有一些好处:

  • 可以处理
    null
    左侧参数
  • 它是非虚拟的-很明显,声明的变量类型是比较 用过
现在一切似乎都很好,我可以继续编码了。直到我发现在基本DTO和扩展DTO之间进行继承的整个想法是有缺陷的。我认为WCF使用的
DataContractSerializer
将序列化函数参数声明为的类型。没有。它序列化对象的实际类型。这意味着,如果一个
PersonExtended
对象被传递给一个只需要
Person
的方法,那么整个扩展方法无论如何都会通过电线传输,因此最好还是坚持简单的组合