Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A generic equality comparer library which will work across types

0.00/5 (No votes)
14 Nov 2013 1  
An extension methods library which could do the equality comparison operations easily

Introduction

The IEnumerable interface provides enough methods and overloads originally and later .NET 3.5 added a huge set of enhancements via extension methods. There are very few cases were a programmer need to kick-in and get his hand dirty to create something which could be used across application development regardless of business or domain. 

Majority of the time, when we perform operations on IEnumerable collections we deal with same object type, or did my life just happened to be like that in past?... Anyway, recently I started seeing a lot of cases where I need to compare or get the instance of an object using a different type. E.g.: To Search/Get the location details of an Employee in a building-space collection, where I have the location collection and the Employee object in hand, and wished I could do something like lstLocation.Exists(employ).   

Background  

Before this library, when I come across such an instance I do not have any alternative but just get out of any built-in methods or LINQ facilities and then write a loop to compare the objects explicitly. Sometimes LINQ helped me here but then I had to struggle with collections from LINQ results for such a simple task. So later I decided to write an extension method which could do the operation for me easily, which I am sharing here. I found these methods are mostly a plus when dealing with LINQ generated anonymous objects, where the original values can no longer be used in any of the operations.  

Demo / Results Screen

Using the code   

Just add the compiled assembly or class library project to your solution and the extension methods will appear in all instances which implements IEnumerable. Refer below for method signatures. 

A quick picture of the code

I do not want to give the whole code in the article itself to make it lengthy and boring. What about some short narrations and let you download the code and see it running?

Project 1: System.Collections.GlobalEquality 

The Library consists of four modules.   

  1. GenericEqualityComparer<T>: I do not claim the ownership of this module.  Essentially, this is where I started with the new library.  It serves as a global comparer when dealing with same instance type as of the collection. This class helps you to use a dummy object and avoid writing equality comparer for every case. But this works only only if you are dealing with the same type. Simply use this class to create an instance of comparer wherever .NET Framework asks for an IEqualityComparer to be passed to the collections. 
  2. Eg: new GenericEqualityComparer<Artist>((x, y) => { return
    x.ID == y.ID; })  
  3. IEqualityComparer<in Source, in Destination>: Base interface, in case anyone wants further extension. 
  4. GenericEqualityComparer<Source, Destination>: This is the core of the library which allows the comparison of two types of objects. The extension methods are provided in library itself which consumes this class. In most cases you do not need to use this class directly; just go with the extension methods. Again yes, you definitely want to make use of this guy in case you think about extending these classes or adding more extension methods. 
  5. Extensions: The methods of this class will be added as extension methods to all the instances of IEnumerable
    1. Contains = Determines whether the specified object is available in the source collection using an external reference and condition. Contains two overloads.
    2. albums.Contains(artists[0], (x, y) => { return x.ArtistID == y.ID; }) 
    3. GetItemBy = Compares the any given object by the provided comparer and returns the matching object from the source collection. Contains two overloads.    
    4. albums.GetItemBy(artists[0], (x, y) => { return x.ArtistID == y.ID; }).AlbumName 
    5. IndexOfBy = Compares the any given object by the provided comparer  and returns the matching object from the source collection. . Contains two overloads.
    6. albums.IndexOfBy(artists[0], (x, y) => { return x.ArtistID == y.ID; })
    7. Any = Determines whether any of the specified objects are available in the source collection. Contains two overloads.
    8. albums.Any(artists, (x, y) => { return x.ArtistID == y.ID; }) 
    9. All = Determines whether all the specified objects are available in the source collection. Contains two overloads.
    10. albums.All(artists, (x, y) => { return x.ArtistID == y.ID; })  
    11. Except = Produces the set difference of two sequences by using the specified IEqualityComparer. Contains two overloads.
    12. albums.Except(artists, (x, y) => { return x.ArtistID == y.ID; })

Project 2: GenericEqualityTest

This solution also include a test module which the results are shown in the above screenshot. It consists of three classes.

  1. Program – Main demo
  2. Artist – Support class to create collection
  3. Album – Support class to create collection

Download source code for complete library and demo. Add comments for improvements and bugs.

History 

  • Base version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here