2016-11-25 223 views
1

我编写了这段代码来检查Collection以找到具有相同值的对象,但它返回索引-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

您创建了一个对象的新实例,你再试图找到对象,其中您的收藏实际持有引用不同的实例的指数。

您可以使用FindIndexToList传入谓词并找到条件为true的对象的索引。 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方法,刚刚比较了参考相等的默认实现。如果您在MyFileInfo中覆盖Equals,则可以决定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,你也应该重写GetHashCodeHere's a discussion。还有一些需要考虑的其他接口,比如IEquatable<T>,尤其是struct(值对象),我猜这个问题已经超出了范围。

编辑Why it's important to override GetHashCode when overriding Equals

+0

嗯,这个解决方案看起来也很有趣。也许我会在周末之后检查一下,如果我能为我的问题做好这项工作。 – Only3lue