Laden...

Effizientes durchsuchen eines List<T>-Objekts

Erstellt von reloop vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.159 Views
reloop Themenstarter:in
139 Beiträge seit 2010
vor 13 Jahren
Effizientes durchsuchen eines List<T>-Objekts

Hallo liebe Community,

ich möchte über meinem DataGrid eine Textbox visualisieren, über welche die Einträge im DataGrid durchsucht werden können.

Das DataGrid ist an ein List<T>-Objekt gebunden. Im Standardfall enthält die List ca. 6.000 Datensätze. Das Element in der Liste bestitzt 20 Properties, die ich durchsuchen möchte.

Nun würde mich interessieren, wir ihr das Lösen würdet.

Momentan vergleiche ich mithilfe von Reflection jede Property ob Sie dem Suchstring entspricht - wenn das nicht der Fall ist - wird das Item aus der Collection entfernt.

Gruss,
reloop

1.552 Beiträge seit 2010
vor 13 Jahren

Hallo reloop,

Reflection ist in diesen Problem sicher ein Flaschenhals. Dir ist das Object doch bekannt. Verwende die Where<T>(Func<T, Boolean>) Linq-Erweiterung.

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

5.658 Beiträge seit 2006
vor 13 Jahren

Momentan vergleiche ich mithilfe von Reflection jede Property ob Sie dem Suchstring entspricht - wenn das nicht der Fall ist - wird das Item aus der Collection entfernt.

Eine andere Möglichkeit hast du erstmal nicht. Du könntest z.B. auf Reflection verzichten, wenn du wüßtest, wie die einzelnen Properties heißen. Also, wenn die Datentypen oder zumindest deren Interface auch bekannt sind.

Um das Durchsuchen zu beschleundigen, könntest du dir überlegen, ob du mit deinem Datenmodell eine Art Index aufbauen kannst, mit dem du die Ergebnisse in kürzerer Zeit abfragen könntest.

Weeks of programming can save you hours of planning

1.029 Beiträge seit 2010
vor 13 Jahren

Hi,

auf SourceFourge gäbe es auch eine BindingListView, welche du dazu benutzen könntest
das Ganze zu filtern. (Funzt allerdings nur über Delegaten)
Ist im Grunde genommen eine Art DataView für Objektlisten.

Als Alternative zu Reflection gibts hier im Forum nach den IDynamicAccessor (ziemlich flott)

Gruß
Achim

S
443 Beiträge seit 2008
vor 13 Jahren

Ich kenne Deinen Code nicht, aber ich würde mir erwarten diesen oder ähnlichen Code zu finden:


{
  string searchedValue = "My Name"; // 1

  BoundElement boundElement = new BoundElement("My Name", 32); // 2

  bool matchReflection = FilterElement(boundElement, "Name", searchedValue); //3
}

public bool FilterElement(BoundElement element, string propertyName, object searchedValue)
{
  PropertyInfo propertyInfo = element.GetType().GetProperty(propertyName); // 4
  object propertyValue = propertyInfo.GetValue(element, null);
  return object.Equals(propertyValue, searchedValue);
}

1: Der Kern ist, irgendwo wird definiert nach was gesucht werden soll
2: Irgendwo wird ein Element erzeugt das gegen die Liste gebunden ist ( T )
3: irgendwo wird die Suche angestossen wo definiert wird welche Property durchsucht werden soll
4: irgendwo wird mittels Reflection der Wert der Property des gebundenen elements ausgelesen.

Die Reflection ist langsam, ich hab mal den Satz fallen lassen:
"Man kennt sich dann mit Reflection aus, wenn man versucht sie zu vermeiden."

wie vermeidet man die Reflection in diesem Fall:

{
  string searchedValue = "My Name";

  BoundElement boundElement = new BoundElement("My Name", 32);
  Func<BoundElement, bool> filterFunc = new Func<BoundElement, bool>((element) =>
    {
      return element.Name == searchedValue;
    });

  bool matchFunc = FilterElement(boundElement, filterFunc);
}

public bool FilterElement(BoundElement element, Func<BoundElement, bool> filterFunc)
{
  return filterFunc(element);
}

an der Stelle in der festgelegt wird welche Property durchsucht werden soll, erstellt man eine Func wie oben und gibt diese statt dem PropertyNamen weiter.
Und weg ist die Reflection.
es wird dadurch nicht wirklich leichter zu verstehen und zu debuggen, aber der Performance Gewinn sollte das aufwiegen. bzw. wenn man damit mehr Erfahrung hat sind die Nachteile auch verschwunden (Das erste Mal debuggen von so einer Struktur hat ein paar Fragezeichen auf meine Stirn gebrannt)

    public class BoundElement
    {

      private string mName;
      private int mAge;

      public BoundElement(string name, int age)
      {
        mName = name;
        mAge = age;
      }

      public string Name
      {
        get { return mName; }
      }

      public int Age
      {
        get { return mAge; }
      }

    }

mbg
Rossegger Robert
mehr fragen mehr wissen

Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen