CustomMatcher
Maps objects by using IMatchMap<TSource, TDestination> (and its static counterpart) and any additional map. Also supports conditional matching.
// Implement the interface(s)
public class MyMaps :
IMatchMap<Product, ProductDto>
{
public bool Match(Product? source, ProductDto? destination, MatchingContext context){
return source?.Id == destination?.Id;
}
}
...
// Create the matcher and retrieve the maps from the given types
var matcher = new CustomMatcher(new CustomMapsOptions{ Types = [ typeof(MyMaps) ] });
...
// Match two objects
if(matcher.Match(myProduct, myProductDto)){
...
}
HierarchyCustomMatcher
Maps objects by using IHierarchyMatchMap<TSource, TDestination> (and its static counterpart) and any additional map. Also supports conditional matching.
// Implement the interface(s)
public class MyMaps :
IHierarchyMatchMap<Product, ProductDto>
{
public bool Match(Product? source, ProductDto? destination, MatchingContext context){
return source?.Id == destination?.Id;
}
}
...
// Create the matcher and retrieve the maps from the given types
var matcher = new HierarchyCustomMatcher(new CustomMapsOptions{ Types = [ typeof(MyMaps) ] });
...
// Match two objects (same type or derived/parent)
if(matcher.Match<Product, ProductDto>(myProduct, myProductDto)){
...
}
if(matcher.Match<LimitedProduct, ProductDto>(myLimitedProduct, myProductDto)){
...
}
if(matcher.Match<Product, LimitedProductDto>(myProduct, myLimitedProductDto)){
...
}
CollectionMatcher
Matchee collections by using another IMatcher to match elements. Different matching options are available, defined in CollectionMatchersOptions. See also CollectionMatchersOptions.
// Create the matcher
var matcher = new CollectionMatcher(new CustomMatcher(...)); // Use any matcher
...
// Match two collections
IEnumerable<Product> myProducts = ...;
IList<ProductDto> myProductDtos = ...;
if(matcher.Match(myProducts, myProductDtos)){
...
}
CompositeMatcher
Delegates matching to other IMatchers. All the matchers are tried in the provided order.
// Create the matcher
var matcher = new CompositeMatcher(
new CustomMatcherr(...),
new CollectionMatcher(new CustomMatcher(...)),
...
);
...
// Match objects
if(matcher.Match(myProduct, myProductDto)){
...
}
if(matcher.Match(myProducts, myProductDtos)){
...
}
EquatableMatcher
Matches classes implementing IEquatable<T>. The types are matched in the provided order: source type is checked for the interface. Singleton matcher.
if(EqualityOperatorsMatcher.Instance.Match<TimeOnly, TimeOnly>(myTime1, myTime2)){
...
}
StructuralEquatableMatcher
Matches classes implementing IStructuralEquatable. Objects need to be of the same type (or derived). Singleton matcher.
// Match two tuples
if(StructuralEquatableMatcher.Instance.Match<(int, bool), (int, bool)>((1, true), (1, true))){
...
}
ObjectEqualsMatcher
Matches by invoking Object.Equals(object, object) (and overloads). Singleton matcher.
if(ObjectEqualsMatcher.Instance.Match<TimeOnly, TimeOnly>(myTime1, myTime2)){
...
}
EqualityOperatorsMatcher (.NET 7+)
Matches classes implementing IEqualityOperators<TSelf, TOther, bool>. The types are matched in the provided order: source type is checked for the interface. Singleton matcher.
if(EqualityOperatorsMatcher.Instance.Match<TimeOnly, TimeOnly>(myTime1, myTime2)){
...
}
NullableMatcher
Matches Nullable<T> and its underlying types by using another IMatcher.
// Implement the interface(s)
public class MyMaps :
IMatchMap<DateTime, string>
{
public bool Match(DateTime source, string? destination, MatchingContext context){
return source.ToString("O") == destination;
}
}
...
// Create the matcher and retrieve the maps from the given types
var matcher = new NullableMatcher(new CustomMatcher(new CustomMapsOptions{ Types = [ typeof(MyMaps) ] }));
...
// Match two objects (they all return true)
if(matcher.Match<DateTime, string>(new DateTime(2025, 08, 31, 19, 21, 16, DateTimeKind.Utc), "2025-08-31T19:21:16Z")){
...
}
if(matcher.Match<DateTime?, string>(new DateTime(2025, 08, 31, 19, 21, 16, DateTimeKind.Utc), "2025-08-31T19:21:16Z")){
...
}
if(matcher.Match<DateTime?, string>(null, null)){
...
}
DelegateMatcher
Matches by invoking a delegate (used to define custom matchers for collections for example).
// Create the matcher
var matcher = DelegateMatcher.Create<Product, ProductDto>((s, d, c) => s?.Id == d?.Id);
...
// Match objects
if(matcher.Match(myProduct, myProductDto)){
...
}
EqualityComparerMatcher
Matches by invoking an IEqualityComparer<T>.
// Create the matcher
var matcher = EqualityComparerMatcher.Create<Product>(myComparer);
...
// Match objects
if(matcher.Match<Product, Product>(myProduct1, myProduct2)){
...
}