2016-11-25 5 views
1

Я написал этот код, чтобы проверить коллекцию, чтобы найти объекты с тем же значением, но возвращает индекс -1 и вызывает исключение IndexOutOfRangeException. Может ли кто-нибудь помочь найти мою ошибку?C# ObservableCollection.IndexOf (...) возвращает -1

List<MyFileInfo> selectedItemsList = dataInbox.SelectedItems.Cast<MyFileInfo>().ToList(); 
foreach (MyFileInfo file in selectedItemsList) 
{ 
    if (!file.AdditionalColumn.Equals("")) 
    { 
     inDB = new ZeichnungInDB(file.FileInfo.Name, file.AdditionalColumn, file.AdditionalColumn2, file.FileInfo.Extension, 
     txtAenderungExtern.Text, file.AdditionalColumn3, 
     int.Parse(txtProjectNumber.Text), txtTag.Text, bemerkung, anhangPfad, cmbDokumententyp.Text, false); 
     if (zeichnungCollection.Count > 0) 
     { 
      if (zeichnungCollection[zeichnungCollection.IndexOf(inDB)].Zeichnungsnummer != inDB.Zeichnungsnummer && 
      zeichnungCollection[zeichnungCollection.IndexOf(inDB)].Extension != inDB.Extension) 
      { 
       zeichnungCollection.Add(inDB); 
      } 
      else 
      { 
       sameData = true; 
      } 
     } 
     else 
     { 
      zeichnungCollection.Add(inDB); 
     } 
    } 
} 
+0

На форматирование кода: Отступ весь блок так, чтобы внешний уровень имеет четыре пространства отступа, и вы должны быть хорошо. –

ответ

1

Вы создаете новый экземпляр объекта, вы затем пытаетесь найти индекс этого объекта, где ваша коллекция действительно держит ссылку на другой экземпляр.

Вы можете использовать FindIndex с ToList, чтобы передать предикат и найти индекс объекта, где условие истинно. https://msdn.microsoft.com/en-us/library/x1xzf2ca(v=vs.110).aspx

В качестве альтернативы, вы можете использовать FirstOrDefault с проверкой некоторых нулевое значение, если вы предпочитаете, чтобы сохранить его как ObservableCollection https://msdn.microsoft.com/en-us/library/bb340482(v=vs.110).aspx

+0

Хм, у меня нет метода FindIndex. – Only3lue

+0

'zeichnungCollection.ToList(). FindIndex (Predicate)' – ColinM

+0

Okey, спасибо! – Only3lue

1

Предположим MyFileInfo выглядит следующим образом:

public class MyFileInfo 
{ 
    public string Name { get; set; } 
} 

Теперь попробуйте использовать это так:

List<MyFileInfo> selectedItemsList = new List<MyFileInfo> 
    { 
     new MyFileInfo { Name = "One" }, 
     new MyFileInfo { Name = "Two" }, 
    }; 

MyFileInfo two = new MyFileInfo { Name = "Two" }; 
int index = selectedItemsList.IndexOf(two); // index == -1 

IndexOf ищет идентичные экземпляры экземпляров, которые он не находит, и поэтому возвращает -1.

Если вы сделаете это вместо того, чтобы, хотя ссылки одинаковы:

MyFileInfo two = new MyFileInfo { Name = "Two" }; 
List<MyFileInfo> selectedItemsList = new List<MyFileInfo> 
    { 
     new MyFileInfo { Name = "One" }, 
     two, 
    }; 

int index = selectedItemsList.IndexOf(two); // index == 1 

Это связано с реализацией по умолчанию в Equals метода, который просто сравнивает для справки равенства. Если вы переопределяете Equals в MyFileInfo, вы можете решить, что означает Equals. Например:

public class MyFileInfo 
{ 
    public string Name { get; set; } 

    public override bool Equals(object obj) 
    { 
     if (obj?.GetType() == typeof(MyFileInfo)) 
     { 
      return ((MyFileInfo)obj).Name == Name; 
     } 

     return false; 
    } 
} 

Это найдет любой объект с таким же Name.

Использование методов с предикатами другой вариант, который позволяет определить, что означает Equals на лету, например .:

List<MyFileInfo> selectedItemsList = new List<MyFileInfo> 
    { 
     new MyFileInfo { Name = "One" }, 
     new MyFileInfo { Name = "Two" }, 
    }; 

MyFileInfo two = new MyFileInfo { Name = "Two" }; 
int index = selectedItemsList.FindIndex(info => info.Name == two.Name); 

Который также находит элементы с одинаковыми Name.

Примечание: Если переопределить Equals в любом классе, который может быть использован в качестве ключа словаря (хэш-таблицы), вы должны также переопределить GetHashCode. Here's a discussion. И есть соображения для реализации различных других интерфейсов, таких как IEquatable<T>, особенно для struct s (объекты значения), которые, как я полагаю, не подходят для этого вопроса.

Edit: Why it's important to override GetHashCode when overriding Equals

+0

Хм, это решение выглядит интересным. Возможно, я проверю это после выходных, если я смогу сделать эту работу для своей проблемы. – Only3lue

Смежные вопросы