fox06
fox06

Reputation: 35

C# Best way to compare fields of class

I need to have possibility of comparison of Product, AdvancedProduct (and other classes that inherit from class Product) How it is better to realize hierarchical check of fields? For example, i want to check two AdvancedProduct classes, first i check fields the basic class Product then check additional fields of AdvancedProduct and return in some form (???) changes between them (maybe class PChanges???). Whether there is a suitable template? How make all this, but to make rather flexibly for the subsequent use?

        public class Product
    {
        public string ID;
        public string Name;

        public Product(string id, string name)
        {
            this.ID = id;
            this.Name = name;
        }


    }

    public class AdvancedProduct : Product
    {
        public string CurrentVersion;

        public AdvancedProduct(string id, string name, string version)
            : base(id, name) { }
    }

    public class PChanges
    {
        public bool NameChanged = false;
        public bool VersionChanged = false;

        public PChanges() { }

    }

    public class ProductComparer
    {
        PChanges changes = new PChanges();

        public ProductComparer() { }

        public PChanges Compare(AdvancedProduct p1, AdvancedProduct p2)
        {
            if (p1.Name != p2.Name)
                changes.NameChanged = true;
            if (p1.CurrentVersion != p2.CurrentVersion)
                changes.VersionChanged = true;

            return changes;

        }
    }

Upvotes: 1

Views: 2344

Answers (3)

Fendy
Fendy

Reputation: 4643

Based on Uzzy's answer, looks like it can be extended to track the change. It is bad practice, yes, but for small app it should be enough. Example:

public class ProductComparer : IEqualityComparer<Product>{
    private PChanges change;
    public PChanges Changes{ get { return change; } }

    public bool Equals(Product p1, Product p2){
        PChanges newChange = new PChanges();
        bool equal = true;
        if(p1.Name != p2.Name){
            newChange.NameChange = true;
            equal = false;
        }
        this.change = newChange;
        return equal;
    }
}

EDIT:

I misread the requirement of extendable field comparison. If that is the case, then Decorator pattern is the best for you. Assuming that every other Product class should be inherited from Product class.

public class ProductComparer{
    public virtual void TrackChange(Product p1, Product p2, ref PChange change){
        if(p1.Name != p2.Name){
            change.NameChange = true;
        }
        // other base validation
    }
}

public class AdvancedProductComparer : ProductComparer{
    public AdvancedProductComparer(ProductComparer baseComparer){
        this.baseComparer = baseComparer;
    }
    ProductComparer baseComparer;

    public override void TrackChange(Product p1, Product p2, ref PChange change){
        baseComparer.Compare(p1, p2, ref change);
        if( ((AdvancedProduct)p1).CurrentVersion != ((AdvancedProduct)p2).CurrentVersion){
            change.CurrentVersion = true;
        }
    }
}

public class ProductComparerService{
    public ProductComparerService(ProductComparer comparer){
        this.comparer = comparer;
    }

    ProductComparer comparer;
    private PChanges change;
    public PChanges Changes{ get { return change; } }

    public bool Equals(Product p1, Product p2){
        PChanges newChange = new PChanges();
        comparer.Compare(p1,p2, ref newChange);            

        this.change = newChange;
        return (newChange.CurrentVersion || newChange.NameChange);
    }
 }

The usage:

ProductComparer pCompare = new ProductComparer();
AdvancedProductComparer advCompare = new AdvancedProductComparer(pCompare);
ProductComparerService service = new ProductComparerService(advCompare);
if( service.Equals(p1,p2) ){
    PChange change = service.Change;
}

Upvotes: 0

Ivailo Karamanolev
Ivailo Karamanolev

Reputation: 823

There is a nice library for .NET called Compare .NET Objects. It can be used to compare complex objects without writing comparison code. It is also quite customizable - you can tell it to exclude certain properties, include others, etc. It can compare both flat objects and object hierarchies. You can download it from CodePlex - http://comparenetobjects.codeplex.com/.

Upvotes: 1

Uzzy
Uzzy

Reputation: 550

It is better when ProductComparer would implement IEqulaityComparer

For more details see the example in given link.

Upvotes: 0

Related Questions