Compare lists with user objects that share a common superclass

I have a metamodel that builds like this:

class ModelElement
{
    string id;
}

class Package : ModelElement
{
     List<Package> nestedPackages;
     List<Class> ownedClasses;
}

class Class : ModelElement
{
}

Now I have created two Models, and I want to check if they are identical. I would like to compare the element IDs, and I do not want to write a method for any type of element.

Package a; //pretend both have classes
Package b; //and nested packages
compare(a.nestedPackages, b.nestedPackages);
compare(a.ownedClasses; b.OwnedClasses);

Since the class and package both inherit from ModelElement, both have identifiers. So I want to write a compare function that compares identifiers. I was thinking about using Generics, but the generic data type does not have an id attribute. Any ideas?

+3
source share
3 answers

You can look Enumerable.SequenceEqualin conjunction with custom mapping.

bool equal = Enumerable.SequenceEqual(a.nestedPackages, b.nestedPackages,
    new ModelElementComparer());

public class ModelElementComparer : IEqualityComparer<ModelElement>
{
    public bool Equals(ModelElement x, ModelElement y)
    {
        return x.id == y.id;
    }

    public int GetHashCode(ModelElement obj)
    {
        return x.id;
    }
}

MSDN SequenceEqual IEqualityComparer.

+4

Object.Equals() ModelElement

public override bool Equals(Object obj) 
{
   //Check for null and compare run-time types.
   if (obj == null || GetType() != obj.GetType()) 
      return false;
   ModelElement m = (ModelElement)obj;
   return (id == m.id);
}

Object.GetHashCode(), .

+1

Something like Linq Exceptwith a custom comparator might work here:

http://msdn.microsoft.com/en-us/library/system.linq.enumerable.except.aspx

An empty final enumeration will mean that there are no differences.

0
source

All Articles