2016-11-25 5 views
1

Ich habe diesen Code geschrieben, um eine Collection auf Objekte mit demselben Wert zu überprüfen, aber sie gibt den Index -1 zurück und verursacht eine IndexOutOfRangeException. Kann mir jemand helfen, meinen Fehler zu finden?C# ObservableCollection.IndexOf (...) liefert -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

Auf Code-Formatierung: Ihre gesamte Block einrücken, so dass die äußerste Ebene vier Räume der Gedankenstrich hat, und Sie sollten gut sein. –

Antwort

1

Sie eine neue Instanz eines Objekts zu schaffen, versuchen Sie dann den Index des Objekts, wo Ihre Sammlung Verweis auf eine andere Instanz tatsächlich hält zu finden.

Sie können FindIndex mit ToList verwenden, um ein Prädikat zu übergeben und den Index des Objekts zu finden, in dem eine Bedingung erfüllt ist. https://msdn.microsoft.com/en-us/library/x1xzf2ca(v=vs.110).aspx

Alternativ Sie FirstOrDefault mit einigen null Kontrolle verwenden können, wenn Sie es als ObservableCollection https://msdn.microsoft.com/en-us/library/bb340482(v=vs.110).aspx

+0

Hm, ich habe keine FindIndex-Methode. – Only3lue

+0

'zeichnungCollection.ToList(). FindIndex (Prädikat)' – ColinM

+0

Okey, danke! – Only3lue

1

MyFileInfo sieht wie folgt aus Angenommen halten würde es vorziehen:

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

Jetzt versuchen zu verwenden, es ist wie folgt:

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 sucht nach identischen Instanzreferenzen, die nicht gefunden werden, und gibt -1 zurück.

Wenn Sie diese stattdessen tun, aber sind die Referenzen der gleiche:

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

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

Dies ist auf die Standardimplementierung der Equals Methode zurückzuführen, die nur als Referenz Gleichheit vergleicht. Wenn Sie Equals in MyFileInfo überschreiben, können Sie entscheiden, was Equals bedeutet. Zum Beispiel:

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; 
    } 
} 

Dies wird jedes Objekt mit dem gleichen Name finden.

mit Prädikaten Verwendung von Methoden ist eine weitere Option, die Sie definieren kann, was Equals bedeuten, on the fly, z.B .:

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); 

Welche auch Elemente mit den gleichen Name findet.

Hinweis: Wenn Sie Equals in jeder Klasse überschreiben, die als Wörterbuch (Hash-Tabelle) Schlüssel verwendet werden können, sollten Sie auch GetHashCode außer Kraft setzen. Here's a discussion. Und es gibt Überlegungen zur Implementierung verschiedener anderer Schnittstellen wie IEquatable<T>, speziell für struct s (Wertobjekte), was meiner Meinung nach für diese Frage nicht möglich ist.

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

+0

Hm, diese Lösung sieht auch interessant aus. Vielleicht werde ich das nach dem Wochenende überprüfen, ob ich das für mein Problem machen kann. – Only3lue

Verwandte Themen