AndiH
AndiH

Reputation: 602

Compare Lists with custom objects, which have a common superclass

I have a Metamodel that's built like this:

class ModelElement
{
    string id;
}

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

class Class : ModelElement
{
}

Now I've built two Models and I want to check if they're identical. I'd like to compare the ID's of the Elements and I don't 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 Class and Package both inherit from ModelElement, both have IDs. So I want to write a Function "compare" which compares the IDs. I thought of using Generics but the generic datatype doesn't have the attribute "id". Any ideas?

Upvotes: 3

Views: 4516

Answers (3)

David M
David M

Reputation: 72900

You could look at Enumerable.SequenceEqual, combined with a custom comparer.

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;
    }
}

Here are MSDN links to this particular SequenceEqual override and the IEqualityComparer interface.

Upvotes: 4

figabytes
figabytes

Reputation: 303

Instead of writing a compare method, you could override the Object.Equals() method on the ModelElement class

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);
}

You will also need to override Object.GetHashCode() as well if you do this.

Upvotes: 2

Adam Houldsworth
Adam Houldsworth

Reputation: 64517

Something like Linq's Except with a custom comparer might work here:

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

An empty resulting enumerable will mean there are no differences.

Upvotes: 0

Related Questions