紹介
Objects Comparerは、オブジェクト比較のためのツールです。C#でよく使われるデータ構造は、このサードパーティライブラリを使って比較できます。複雑なオブジェクトも比較可能です。
簡単に言うと、Objects Comparerはオブジェクト間の比較器であり、メンバーごとに再帰的にオブジェクトを比較し、特定のプロパティ、フィールド、または型に対してカスタム比較ルールを定義できます。
インストール
nuget で ObjectsComparer を検索:

使用法
まず、簡単なクラスを定義します:
public class UserInfomation
{
public string Name { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
}
2つの UserInfomation オブジェクトをインスタンス化し、異なる値を代入し、ObjectsComparer.Comparer 比較器をインスタンス化します:
var comparer1 = new ObjectsComparer.Comparer<UserInfomation>();
次に、インスタンス化した2つのオブジェクトを ObjectsComparer.Comparer メソッドに渡します:
IEnumerable<Difference> differences1;
var isEqual1 = comparer1.Compare(userInfomationOld, userInfomationNew, out differences1);
戻り値でオブジェクトが一致するかどうかを判断し、一致しない場合は differences1 を使って不一致の値を取得できます。
出力を見ると、2つのインスタンスの age プロパティの値が異なることがわかります:

次に、List<T> 型を試してみます:
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);
出力を見ると、件数が一致しない問題であることがわかります:

適用シナリオ
.NET クライアント開発を経験した方ならご存知の通り、基本データを保守する際にデータ編集は避けられません。
編集ページを開いて実際にデータを変更しなかった場合、保存ボタンを押すときに、各フィールドを1つずつ比較して変更があったかどうかを確認するか、あるいは単純に変更をチェックせずに直接 update インターフェースを呼び出すという乱暴な方法をとることがあります。
そこで、Objects Comparer が役立ちます。まず BaseForm をカプセル化し、基本クラスコントロールに比較メソッドをカプセル化します:
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; }
}
編集ページを開くときに現在のページのデータを読み込みます。このとき、編集前のデータを取得してグローバル変数として設定し、保存時には編集後のオブジェクトを取得して基本クラスの比較メソッドを呼び出します。
2つのオブジェクト間で値が変更されているかどうかを確認し、変更がない場合は「データが変更されていません。フォームを閉じますか?」などのメッセージを表示します:
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 = "张三";
test.Age = 30;
test.Sex = "男";
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("データが変更されていません");
return;
}
// その後、保存ロジックを記述
MessageBox.Show("保存成功");
}
}
public class Test
{
public string Name { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
}
もちろん他にも多くの適用シナリオがありますが、ここでは私がよく使うシナリオを紹介しました。
最後に、皆さん(neter)がもっと便利なツールを共有し、一緒に .NET 環境を改善していくことを願っています!