Ignore property with list type with DeepEquals

Having a look through the source code of DeepEqual, the library allows for custom comparisons via the IComparison interface. With that, I simulated the models that you require:

public class MyClass
{
    public MyClass()
    {
        MyList = new List<MySubClass>(new[]
        {
            new MySubClass {Id = Guid.Parse("1".PadLeft(32, '0')), Name = "Foo"}, 
            new MySubClass {Id = Guid.Parse("2".PadLeft(32, '0')), Name = "Bar"}, 
            new MySubClass {Id = Guid.Parse("3".PadLeft(32, '0')), Name = "Test"}, 
        });
    }

    public MyClass(params MySubClass[] subs)
    {
        MyList = new List<MySubClass>(subs);
    }
    
    public List<MySubClass> MyList { get; set; }
}

public class MySubClass
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

Then I went on to creating a custom IComparison class:

public class MySubClassComparer : IComparison
{
    public bool CanCompare(Type type1, Type type2)
    {
        return type1 == type2 && type1 == typeof(MySubClass);
    }

    public (ComparisonResult result, IComparisonContext context) Compare(IComparisonContext context, object value1, object value2)
    {
        if (value1 is MySubClass first && value2 is MySubClass second)
        {
            if (first.Name == second.Name)
            {
                return (ComparisonResult.Pass, context);
            }
        }

        return (ComparisonResult.Fail, context);
    }
}

Here are both of my passing unit tests:

[Fact]
public void IsDeepEqual_ShouldReturnTrue_WhenListHasSameNames()
{
    // Arrange
    MyClass sut = new MyClass();
    MyClass parameter = new MyClass(new[]
    {
        new MySubClass {Id = Guid.Parse("4".PadLeft(32, '0')), Name = "Foo"},
        new MySubClass {Id = Guid.Parse("5".PadLeft(32, '0')), Name = "Bar"},
        new MySubClass {Id = Guid.Parse("6".PadLeft(32, '0')), Name = "Test"},
    });
    var comparer = new ComparisonBuilder().WithCustomComparison(new MySubClassComparer()).Create();

    // Act
    bool result = sut.IsDeepEqual(parameter, comparer);

    // Assert
    Assert.True(result);
}

[Fact]
public void IsDeepEqual_ShouldReturnFalse_WhenListHasDifferentNames()
{
    // Arrange
    MyClass sut = new MyClass();
    MyClass parameter = new MyClass(new[]
    {
        new MySubClass {Id = Guid.Parse("4".PadLeft(32, '0')), Name = "Foo"},
        new MySubClass {Id = Guid.Parse("5".PadLeft(32, '0')), Name = "Bar"},
        new MySubClass {Id = Guid.Parse("6".PadLeft(32, '0')), Name = "Fail"},
    });
    var comparer = new ComparisonBuilder().WithCustomComparison(new MySubClassComparer()).Create();

    // Act
    bool result = sut.IsDeepEqual(parameter, comparer);

    // Assert
    Assert.False(result);
}

Notes This comparison should ignore the Id property, but am unsure if this is the best way to accomplish the task. There’s an IgnoreProperty method which might be better suited for the task, but couldn’t see a way to get it to work currently.

If anyone has more experience then I do with the library, please let me know of better ways, and I’ll update my answer accordingly.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top