ObservableCollection IndexOf
Как то раз, необходимо было выяснить, содержит ли коллекция ObservableCollection элемент. Благо, у ObservableCollection есть метод IndexOf который возвращает индекс элемента, если он есть в коллекции. Но не всё так гладко. Рассмотрим пример ниже:
using System; using System.Collections.Generic; using System.Text; using System.Collections.ObjectModel; namespace ObservableCollectionIndexOf { class Program { static ObservableCollection<Data> DataCollection; static Data _data; static void Main(string[] args) { DataCollection = new ObservableCollection<Data>(); //заполняем коллекцию for (int i = 0; i < 10; i++) { _data = new Data(i); DataCollection.Add(_data); Console.WriteLine(DataCollection.IndexOf(_data)); } _data = new Data(4); Console.WriteLine(DataCollection.IndexOf(_data)); Console.ReadKey(); } } class Data { public int Id { get; set; } public string Name { get; set; } public Data(int Id) { this.Id = Id; Name = "Name " + Id; } } }
Результат оказывается немножко другим, чем можно ожидать. В случае, когда проверяется объект, который был добавлен в коллекцию (проверка сразу после добавления), то возвращается индекс добавленного элемнта. Когда же мы создаем новый элемент и проверяем его наличие в коллекции, то получаем результат -1, то есть – элемент не найден. Оказывается, IndexOf проверяет совпдадение ссылок на объекты, а не самих объектов.
Я нашёл несколько решений этой проблемы. Одна из них, это сделать класс Data структурой, но это не всегда подходит разработчику. Второе решение – реализовать в классе интерфейс IEquatable. Также, хорошей идеей будет переопределить метод GetHashCode. В результате имеем класс и отлично работающий метод IndexOf
class Data : IEquatable<Data> { public int Id { get; set; } public string Name { get; set; } public Data(int Id) { this.Id = Id; Name = "Name " + Id; } #region IEquatable<Data> Members public bool Equals(Data other) { if (this.Id == other.Id) return true; return false; } #endregion public override int GetHashCode() { return Id.GetHashCode(); } }
Исходники:
ObservableCollectionIndexOf.rar (20,0 KiB, 1 126 закачек)