Skip to content

Custom Comparers

Greg Finzer edited this page Nov 18, 2019 · 7 revisions

Implementing a Custom Comparer by implementing BaseTypeComparer

To add a custom comparer, implement BaseTypeComparer and add to the Config.CustomComparers collection. Custom comparers are run before the built in comparers.

Example

public class MyCustomComparer : BaseTypeComparer
{
	public MyCustomComparer(RootComparer rootComparer) : base(rootComparer)
	{
	}

	public override bool IsTypeMatch(Type type1, Type type2)
	{
		return type1 == typeof (SpecificTenant);
	}

	public override void CompareType(CompareParms parms)
	{
		var st1 = (SpecificTenant)parms.Object1;
		var st2 = (SpecificTenant)parms.Object2;

		if (st1.Name != st2.Name || st1.Amount > 100 || st2.Amount < 100)
		{
			AddDifference(parms);
		}
	}
}

Usage

CompareLogic compareLogic = new CompareLogic();

SpecificTenant tenant1 = new SpecificTenant();
tenant1.Name = "wire";
tenant1.Amount = 37;

SpecificTenant tenant2 = new SpecificTenant();
tenant2.Name = "wire";
tenant2.Amount = 155;            

//No Custom Comparer
Assert.IsFalse(compareLogic.Compare(tenant1, tenant2).AreEqual);

//specify custom selector
compareLogic.Config.CustomComparers.Add(new MyCustomComparer(RootComparerFactory.GetRootComparer()));

Assert.IsTrue(compareLogic.Compare(tenant1, tenant2).AreEqual);

tenant2.Amount = 42;
Assert.IsFalse(compareLogic.Compare(tenant1, tenant2).AreEqual);

Implementing a Custom Comparer with a function

CompareLogic compareLogic = new CompareLogic();

SpecificTenant tenant1 = new SpecificTenant();
tenant1.Name = "wire";
tenant1.Amount = 37;

SpecificTenant tenant2 = new SpecificTenant();
tenant2.Name = "wire";
tenant2.Amount = 155;

//No Custom Comparer
Assert.IsFalse(compareLogic.Compare(tenant1, tenant2).AreEqual);

//specify custom selector
//using the same rule as MyCustomComparer
compareLogic.Config.CustomComparers.Add(new CustomComparer<SpecificTenant, SpecificTenant>(
	(st1, st2) => !(st1.Name != st2.Name || st1.Amount > 100 || st2.Amount < 100)
));

Assert.IsTrue(compareLogic.Compare(tenant1, tenant2).AreEqual);

tenant2.Amount = 42;
Assert.IsFalse(compareLogic.Compare(tenant1, tenant2).AreEqual);

//Change rule at runtime
var comparerer = compareLogic.Config.CustomComparers[0] as CustomComparer<SpecificTenant, SpecificTenant>;
comparerer.Compare = (st1, st2) => !(st1.Name != st2.Name || st1.Amount > 100 || st2.Amount < 40);
Assert.IsTrue(compareLogic.Compare(tenant1, tenant2).AreEqual);

Custom Class Property Comparer

var config = new ComparisonConfig();
config.CustomPropertyComparer<Officer>(officer => officer.ID,
	new CustomComparer<int, int>((i, i1) => i % 2 == 1));

var deriveFromOfficer1 = new Officer { ID = 1, Name = "John", Type = Deck.Engineering };
var deriveFromOfficer2 = new Officer { ID = 2, Name = "John", Type = Deck.Engineering };

var derive2FromOfficer1 = new Derive2FromOfficer { Email = "a@a.com", ID = 3, Name = "John", Type = Deck.Engineering };
var derive2FromOfficer2 = new Derive2FromOfficer { Email = "a@a.com", ID = 4, Name = "John", Type = Deck.Engineering };

var compare = new CompareLogic(config);

var result = compare.Compare(deriveFromOfficer1, deriveFromOfficer2);
Assert.IsTrue(result.AreEqual);

result = compare.Compare(derive2FromOfficer1, derive2FromOfficer2);
Assert.IsTrue(result.AreEqual);