C# Using Objects Comparer for Object Comparison

C# Using Objects Comparer for Object Comparison

Objects Comparer is a tool for object comparison. Common data structures in C# can be compared using this third-party library, and even complex objects can be compared.

Last updated 7/15/2022 9:55 PM
黑哥聊dotNet
4 min read
Category
.NET
Tags
.NET C#

Introduction

Objects Comparer is a tool for object comparison. Common data structures in C# can be compared using this third-party library, and even complex objects are comparable.

In short, Objects Comparer is an object-to-object comparer that allows recursive member-by-member comparison and enables custom comparison rules for specific properties, fields, or types.

Installation

Search for ObjectsComparer on NuGet:

Usage

First, define a simple class:

public class UserInfomation
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Sex { get; set; }
}

Instantiate two UserInfomation objects with different values, then instantiate the ObjectsComparer.Comparer comparer:

var comparer1 = new ObjectsComparer.Comparer<UserInfomation>();

Now pass the two objects to the Compare method of ObjectsComparer.Comparer:

IEnumerable<Difference> differences1;
var isEqual1 = comparer1.Compare(userInfomationOld, userInfomationNew, out differences1);

Use the return value to determine whether the objects are identical. If not, you can retrieve the differing values from differences1.

From the output, we can see that the two objects differ in the Age property:

Now let's test with a List<T> type:

List<UserInfomation> lstUserInfomationsOld = new List<UserInfomation>();
for (int i = 0; i < 3; i++)
{
    UserInfomation user = new UserInfomation();
    user.Name = "张三";
    user.Age = 30;
    user.Sex = "男";
    lstUserInfomationsOld.Add(user);
}
List<UserInfomation> lstUserInfomationsNew = new List<UserInfomation>();
for (int i = 0; i < 2; i++)
{
    UserInfomation user = new UserInfomation();
    user.Name = "李四";
    user.Age = 30;
    user.Sex = "男";
    lstUserInfomationsNew.Add(user);
}

var comparer = new ObjectsComparer.Comparer<List<UserInfomation>>();
IEnumerable<Difference> differences;
var isEqual = comparer.Compare(lstUserInfomationsNew, lstUserInfomationsOld, out differences);
string differencesMsg = string.Join(Environment.NewLine, differences);
Console.WriteLine(differencesMsg);

From the output, we can see that the lists differ in count:

Application Scenarios

Anyone who has done .NET client development knows that when maintaining basic data, editing is inevitable.

Sometimes we open an edit page without actually modifying the data, and then click the Save button. Without Objects Comparer, we would have to either compare each field manually or skip the validation entirely and call the update interface directly.

This is where Objects Comparer comes in handy. First, we create a base form (BaseForm) and encapsulate a comparison method in the base control:

protected Result ComPare<T>(T t, T s)
{
    Result result = new Result();
    var comparer = new ObjectsComparer.Comparer<T>();
    IEnumerable<Difference> differences;
    bool isEqual = comparer.Compare(t, s, out differences);
    result.IsEqual = isEqual;
    if (!isEqual)
    {
        string differencesMsg = string.Join(Environment.NewLine, differences);
        result.Msg = differencesMsg;
    }
    return result;
}

public class Result
{
    public bool IsEqual { get; set; }
    public string Msg { get; set; }
}

When we open an edit page, we load the current data. We can retrieve the unedited object and store it as a global variable. Then, at save time, we obtain the edited object and call the base class comparison method.

If the values have not changed between the two objects, we can prompt the user with a message like "Data not modified. Do you want to close the form?":

public partial class MainFrm : BaseForm
{
    Test _testOld;
    public MainFrm()
    {
        InitializeComponent();
        _testOld = LoadData();
        txtName.Text = _testOld.Name;
        txtAge.Text = _testOld.Age.ToString();
        txtSex.Text = _testOld.Sex;
    }
    private Test LoadData()
    {
        Test test = new Test();
        test.Name = "Zhang San";
        test.Age = 30;
        test.Sex = "Male";
        return test;
    }

    private void uiButton1_Click(object sender, EventArgs e)
    {
        Test test = new Test();
        test.Name = txtName.Text;
        test.Age = int.Parse(txtAge.Text);
        test.Sex = txtSex.Text;
        Result result = ComPare(_testOld, test);
        if (result.IsEqual)
        {
            MessageBox.Show("Data not modified");
            return;
        }
        // Then write the save logic
        MessageBox.Show("Saved successfully");
    }
}
public class Test
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Sex { get; set; }
}

Of course, there are many other application scenarios. I am simply sharing a common one I use.

Finally, I hope all .NET developers share more useful tools to improve the .NET ecosystem together!

Keep Exploring

Related Reading

More Articles