C#中对象的更多信息比较

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#中对象的更多信息比较相关的知识,希望对你有一定的参考价值。

在我的C#测试中,我经常想要比较两个相同类型的对象(通常是预期的对象与实际对象),但我想允许一些灵活性。例如,可能存在我知道的时间戳字段不相等或者在比较对象时我想忽略的某些字段。

最重要的是,我想提供一条信息性消息,描述两个对象属性值的不同之处,以便我能够快速确定问题所在。例如,显示“源属性名称值Fred与目标属性名称值Freda不匹配”的消息。

标准的Equals和Comparer方法似乎只返回int或Booleans,它们不能为我提供足够的信息。目前,我的对象比较方法返回一个包含两个字段(布尔值和消息)的自定义类型,但我的想法是必须有更标准的方法来执行此操作。这些天,也许一个元组可能是要走的路,但我会欢迎建议。

答案

“比较”可能不是你要做的事情。在这方面,这个词已经具有共同的含义。我们比较对象的相等性,它返回一个boolean - 它们相等或不相等。或者我们比较它们以查看哪个更大。返回一个int,它可以表明一个或另一个更大,或者它们是相等的。排序对象时这很有用。

您要做的是确定对象之间的具体差异。我不会尝试编写处理不同类型对象的泛型,除非您打算使它们非常简单。当你进入返回其他复杂对象或集合或复杂对象集合的属性时,这变得非常复杂。与仅仅编写一种比较您想要比较的特定类型的方法相比,这并不是不可能的。

这里有一些接口和类可以使任务更容易和更一致。但说实话,很难说这是怎么做的。而且,如果您处理嵌套的复杂属性,它会变得复杂。如果两个属性都包含某些其他对象的列表会发生什么,并且这些列表中的所有项目都是相同的,除了每一个具有不同属性的项目。或者如果他们都不同呢?在那种情况下,您如何描述父对象的“不等式”?知道它们是否相等可能是有用的,但以某种方式描述差异则不那么重要。

public interface IInstanceComparer<T>
{
    IEnumerable<PropertyDifference> GetDifferences(T left, T right);
}

public abstract class InstanceComparer<T> : IInstanceComparer<T>
{
    public IEnumerable<PropertyDifference> GetDifferences(T left, T right)
    {
        var result = new List<PropertyDifference>();
        PopulateDifferences(left, right, result);
        return result;
    }

    public abstract void PopulateDifferences(T left, T right, 
       List<PropertyDifference> differences);
}

public class PropertyDifference
{
    public PropertyDifference(string propertyName, string leftValue, 
        string rightValue)
    {
        PropertyName = propertyName;
        LeftValue = leftValue;
        RightValue = rightValue;
    }
    public string PropertyName { get; }
    public string LeftValue { get; }
    public string RightValue { get; }
}

public class Animal
{
    public string Name { get; }
    public int NumberOfLimbs { get; }
    public DateTime Created { get; }
}

public class AnimalDifferenceComparer : InstanceComparer<Animal>
{
    public override void PopulateDifferences(Animal left, Animal right, 
        List<PropertyDifference> differences)
    {
       if(left.Name != right.Name) 
           differences.Add(new PropertyDifference("Name", left.Name, right.Name));
       if(left.NumberOfLimbs!=right.NumberOfLimbs) 
           differences.Add(new PropertyDifference("NumberOfLimbs", 
               left.NumberOfLimbs.ToString(), 
               right.NumberOfLimbs.ToString()));
    }
}
另一答案

您可以使用扩展方法来执行此操作。例如:

public static Extensions
{
    public static void CompareWithExpected(this <type> value, <type> expected)
    {
        Assert.AreEqual(expected.Property1, value.Property1, "Property1 did not match expected";
        Assert.AreEqual(expected.Property2, value.Property2, "Property2 did not match expected";
    }
}

然后这可以使用如下:

public void TestMethod()
{
    // Arrange
    ...

    // Act
    ...

    // Assert
    value.CompareWithExpected(expected);
}

您可以使用任意数量的这些扩展方法,从而可以灵活地仅检查某些值等。

这也意味着您不需要使用本质上是测试代码来污染您的类型。

以上是关于C#中对象的更多信息比较的主要内容,如果未能解决你的问题,请参考以下文章

Android - 弹出两个或更多片段但不顶部

C#-WebForm-★内置对象简介★Request-获取请求对象Response相应请求对象Session全局变量(私有)Cookie全局变量(私有)Application全局公共变量Vi(代码片段

几个非常实用的JQuery代码片段

使用嵌套片段和动画对象

Android:使用 putExtra 从片段访问容器活动对象?

如何在活动和片段之间传递对象