Reputation: 602
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
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
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
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