Question

I have the next class:

public class MapsDescModel : NotificationObject, IEqualityComparer<MapsDescModel>
{
    public MapsDescModel(ObservableCollection<MainCategories> mainCategoty)
    {
        MainCategories = mainCategoty;
    }

    private MainCategories _mainCategorySelectedItem;
    public MainCategories MainCategorySelectedItem
    {
        get { return _mainCategorySelectedItem; }
        set
        {
            if (Equals(value, _mainCategorySelectedItem)) return;
            _mainCategorySelectedItem = value;
            RaisePropertyChanged("MainCategorySelectedItem");
            RaisePropertyChanged("SubCategories");
        }
    }

    private SubCategories _subCategorySelectedItem;
    public SubCategories SubCategorySelectedItem
    {
        get { return _subCategorySelectedItem; }
        set
        {
            if (Equals(value, _subCategorySelectedItem)) return;
            _subCategorySelectedItem = value;
            RaisePropertyChanged("SubCategorySelectedItem");
        }
    }

    private ObservableCollection<MainCategories> _mainCategories;
    public ObservableCollection<MainCategories> MainCategories
    {
        get { return _mainCategories; }
        set
        {
            if (Equals(value, _mainCategories)) return;
            _mainCategories = value;
            RaisePropertyChanged("MainCategories");
        }
    }

    public ObservableCollection<SubCategories> SubCategories
    {
        get
        {
            if (MainCategorySelectedItem != null)
                return
                    Infrastructure.Helpers.ExtensionMethods.ToObservableCollection(
                        MainCategorySelectedItem.SubCategory.AsEnumerable());
            else return new ObservableCollection<SubCategories>();
        }
    }


    public bool Equals(MapsDescModel x, MapsDescModel y)
    {
        return
            x.MainCategorySelectedItem.MainCatID == y.MainCategorySelectedItem.MainCatID &&
            x.SubCategorySelectedItem.SubCatID == y.SubCategorySelectedItem.SubCatID;
    }

    public int GetHashCode(MapsDescModel obj)
    {
        if (Object.ReferenceEquals(obj, null)) return 0;

        if (obj.MainCategorySelectedItem == null || obj.SubCategorySelectedItem == null) 
            return 0;
        else  return obj.MainCategorySelectedItem.Category.GetHashCode() + obj.SubCategorySelectedItem.Category.GetHashCode();
    }
}

And i have the next collection in other class:

MapsGrid = new ObservableCollection<MapsDescModel>()

I'm trying to use MapGrid.Distinct() method but it not working as it should.

The properties MainCatID and SubCatID are Integers. When I'm inserting 2 objects with same properties values to the collection and use Distinct method nothing happens. I check by code (Console.WriteLine(MapsGrid[0].Equals(MapsGrid[1]));) what the comparison returns and it returns false even the properties are equal. Where is my mistake?


Update:

I edited MapsDescModel class:

  public class MapsDescModel : NotificationObject, IEqualityComparer<MapsDescModel>, IEquatable<MapsDescModel>
    {
        public MapsDescModel(ObservableCollection<MainCategories> mainCategoty)
        {
            MainCategories = mainCategoty;

        }



        private MainCategories _mainCategorySelectedItem;
        public MainCategories MainCategorySelectedItem
        {
            get { return _mainCategorySelectedItem; }
            set
            {
                if (Equals(value, _mainCategorySelectedItem)) return;
                _mainCategorySelectedItem = value;
                RaisePropertyChanged("MainCategorySelectedItem");
                RaisePropertyChanged("SubCategories");
            }
        }

        private SubCategories _subCategorySelectedItem;
        public SubCategories SubCategorySelectedItem
        {
            get { return _subCategorySelectedItem; }
            set
            {
                if (Equals(value, _subCategorySelectedItem)) return;
                _subCategorySelectedItem = value;
                RaisePropertyChanged("SubCategorySelectedItem");
            }
        }


        private ObservableCollection<MainCategories> _mainCategories;
        public ObservableCollection<MainCategories> MainCategories
        {
            get { return _mainCategories; }
            set
            {
                if (Equals(value, _mainCategories)) return;
                _mainCategories = value;
                RaisePropertyChanged("MainCategories");
            }
        }

        public ObservableCollection<SubCategories> SubCategories
        {
            get
            {
                if (MainCategorySelectedItem != null)
                    return
                        Infrastructure.Helpers.ExtensionMethods.ToObservableCollection(
                            MainCategorySelectedItem.SubCategory.AsEnumerable());
                else return new ObservableCollection<SubCategories>();
            }
        }


        public bool Equals(MapsDescModel x, MapsDescModel y)
        {
            if (x.MainCategorySelectedItem == null || x.SubCategorySelectedItem == null ||
                y.MainCategorySelectedItem == null || y.SubCategorySelectedItem == null)
                return false;

            return
                x.MainCategorySelectedItem.MainCatID == y.MainCategorySelectedItem.MainCatID &&
                x.SubCategorySelectedItem.SubCatID == y.SubCategorySelectedItem.SubCatID;
        }

        public int GetHashCode(MapsDescModel obj)
        {
            if (Object.ReferenceEquals(obj, null)) return 0;

            if (obj.MainCategorySelectedItem == null || obj.SubCategorySelectedItem == null)
                return 0;
            else return obj.MainCategorySelectedItem.Category.GetHashCode() + obj.SubCategorySelectedItem.Category.GetHashCode();
        }

        public bool Equals(MapsDescModel other)
        {
            return
            this.Equals(this, other);  // use definition from IEqualityComparer<T>
        }

        public override bool Equals(object obj)
        {
            MapsDescModel other = obj as MapsDescModel;
            if (other == null)
                return base.Equals(obj);
            else
                return this.Equals(other);
        }

        public override int GetHashCode()
        {
            MapsDescModel other = this as MapsDescModel;
            if (other == null)
                return base.GetHashCode();
            else
                return this.GetHashCode(other);
        }

and now when I executing Distinct method it still not working. I know that my Equality method is working because the line 'Console.WriteLine(MapsGrid[0].Equals(MapsGrid[1]));' returns true.

Any ideas?

Was it helpful?

Solution

You've implemented IEqualityComparer<T>, which is fine if you want to pass in an instance of your class to Distinct:

var distinctList = MapGrid.Distinct(new MapsDescModel());

However a cleaner method is to implement IEquatable<T> instead, since Distinct will use that by default if you don't pass in an IEqualityComparer<T>:

public class MapsDescModel : NotificationObject, IEqualityComparer<MapsDescModel>, IEquatable<MapsDescModel>
{
...
    public bool Equals(MapsDescModel y)
    {
        return
            this.Equals(this,y);  // use definition from IEqualityComparer<T>
    }  
}

I would also recommend overriding object.Equals and object.GetHashCode for consistency, again leveraging the IEqualityComparer methods if you like (or just converting the IEqualityComparer methods to overrides if you decide you don't need them anymore).

OTHER TIPS

If you want help then answer the questions asked.

Does override bool Equals(object obj) get called and what does it return?
Your response failed to answer that very critical question.

Since you don't implement Object I suspect those OverRides are not called

Implementing the Equals Method

You are applying IEqualityComparer to a class (MapsDescModel) and it applies to a collection

IEqualityComparer Interface

I think what you need to do (or mean to do) is OverRide GetHashCode and Equals on the class MainCategories
But you don't post the definition for MainCategories
And I find the plur (s) interesting -- is

public ObservableCollection<MainCategories> MainCategories 

a collection of a collection?
Consider not naming a property the name of the class for clarity

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top