none
Alle Instanzen einer Klasse mit List(of T) auslesen ? RRS feed

  • Frage

  • Hallo Forum,

    ist es möglich alle Instanzen einer Klasse mit List(of T) auszulesen?

    lg heinz

    Donnerstag, 1. September 2011 17:23

Antworten

  • Hallo Heinz,

    so wie Du es zeigst, kommen keine Daten (Dateien) in der Liste an.
    Du erzeugst zwar immer eine neue Instanz, weist sie jedoch immer der gleichen Variable zu, und fügst sie nie der Liste hinzu.

    Damit die dateien nach dem verlassen von MeinInitial zur Verfügung steht, müsste sie als Instanz-Variable deklariert werden.
    zeiger hingegen kann lokal in der Prozedur definiert werden, da sie nur zwischendurch den Verweis aufnimmt.
    Und man käme auch ganz ohne aus, wie man sehen sollte:

     
    ' Als Instanz / Klassenvarible
    Dim dateien As New List(Of Datei) 'HIER IST DER FEHLER
     
    Private Sub MeinInitial()
      ' Erstellen...
      Dim zeiger As New Datei() With { _
       .KameraNr = "123", _
       .Dateiname = "C:\TEMP\Datei123.jpg", _
       .Änderungsdatum = Date.Parse("28.04.2011 03:23:15"), _
       .ListenName = "Liste 1", _
       .DateiGröße = 10000}
       
       ' und in die Liste anfügen.
       dateien.Add(zeiger)
       
       ' weitere Instanz erzeugen
      zeiger = New Datei() With { _
       .KameraNr = "124", _
       .Dateiname = "C:\TEMP\Datei124.jpg", _
       .Änderungsdatum = Date.Parse("27.04.2011 12:20:15"), _
       .ListenName = "Liste 2", _
       .DateiGröße = 20000}
       
       ' und anfügen
       dateien.Add(zeiger)
      
      ' oder direkt anfügen
      dateien.Add(New Datei() With { _
       .KameraNr = "123", _
       .Dateiname = "C:\TEMP\Datei125.jpg", _
       .Änderungsdatum = Date.Parse("15.02.2011 23:03:57"), _
       .ListenName = "Liste 1", _
       .DateiGröße = 5000})
       
       dateien.Add(new Datei() With { _
       .KameraNr = "124", _
       .Dateiname = "C:\TEMP\Datei125.jpg", _
       .Änderungsdatum = Date.Parse("2a8.03.2011 01:49:03"), _
       .ListenName = "Liste 1", _
       .DateiGröße = 5000})
       
       ' sollte hier 4 ergeben
       Console.WriteLine("In Dateien sind {0} Elemente enthalten", dateien.Count)
    End Sub
    
    

    Nun kannst Du im weiteren Programmveraluf auf die Dateien zugreifen.
    Und wie im anderen Beispiel sortieren, filtern usw.

    Gruß Elmar

    • Als Antwort markiert Heinz999 Freitag, 2. September 2011 06:20
    Donnerstag, 1. September 2011 22:26
    Beantworter

Alle Antworten

  • Hallo Heinz,

    so ganz verstehe ich Deine Frage nicht.

    Es gibt keine "globale" Verwaltung aller Klasseninstanzen.
    Zwar "weiß" der Garbage Collector, welche Instanzen existieren,
    darauf gibt es aber keinen direkten Zugriff.

    Zudem ist List(Of T) kein konkreter Typ, sondern ein offener.
    Davon können keine realen Instanzen "existieren", dazu muss T konkretisiert werden,
    siehe Reflektion und generische Typen für eine genauere Beschreibung.

    Bitte erkläre genauer, was Du vorhast und evtl. auch warum...

    Gruß Elmar

     

    Donnerstag, 1. September 2011 18:02
    Beantworter
  • Hallo Elmar,

    ich beziehe mich auf ein code-Beispiel im Forum-Beitrag "Array/Structure sortieren" welches die Mitglieder eine Klasse verwendet um sie zu sortieren und zu selektieren. Das möchte ich ebenfalls tun: Nämlich mehrere Member nach einer Eigenschaft selektieren und sie dann zu sortieren.

     

    In der Folge das Code-Beispiel welches diese Dinge tut aber die Members in einen Schwung erstellt. Ich gehe davon aus das die Members in der Klasse bereits vorhanden sind,

    lg heinz

     Public Shared Sub EinlesenUndSortieren()
        Dim dateien As New List(Of Datei) From {
         New Datei() With {
          .KameraNr = "123",
          .Dateiname = "C:\TEMP\Datei123.jpg",
          .Änderungsdatum = Date.Parse("28.04.2011 03:23:15"),
          .ListenName = "Liste 1",
          .DateiGröße = 10000},
         New Datei() With {
          .KameraNr = "124",
          .Dateiname = "C:\TEMP\Datei124.jpg",
          .Änderungsdatum = Date.Parse("27.04.2011 12:20:15"),
          .ListenName = "Liste 2",
          .DateiGröße = 20000},
         New Datei() With {
          .KameraNr = "123",
          .Dateiname = "C:\TEMP\Datei125.jpg",
          .Änderungsdatum = Date.Parse("15.02.2011 23:03:57"),
          .ListenName = "Liste 1",
          .DateiGröße = 5000},
         New Datei() With {
          .KameraNr = "124",
          .Dateiname = "C:\TEMP\Datei125.jpg",
          .Änderungsdatum = Date.Parse("28.03.2011 01:49:03"),
          .ListenName = "Liste 1",
          .DateiGröße = 5000}
        }
    
        Console.WriteLine("Unsortiert:")
        For Each item In dateien
          Console.WriteLine("{0}: {1}", item.Änderungsdatum, item.Dateiname)
        Next
    
        Console.WriteLine("Sortiert nach Änderungsdatum:")
        dateien.Sort(Function(left, right) left.Änderungsdatum.CompareTo(right.Änderungsdatum))
        For Each item In dateien
          Console.WriteLine("{0}: {1}", item.Änderungsdatum, item.Dateiname)
        Next
    
        Console.WriteLine("Gefiltert nach Datum und sortiert nach KameraNr, Dateigröße via LINQ:")
        Dim sortierteDateien = From d In dateien
              Where d.Änderungsdatum > #4/1/2011#
              Order By d.KameraNr, d.DateiGröße
              Select d
        For Each item In sortierteDateien
          Console.WriteLine("{0}: {1}", item.Änderungsdatum, item.Dateiname)
        Next
      End Sub
    
    
    
    
    Public Class Datei
      Public Property KameraNr As String ' Integer ?
      Public Property Dateiname As String
      Public Property Änderungsdatum As Date
      Public Property ListenName As String
      Public Property DateiGröße As Long ' halbe Bytes gibt es nicht
    End Class
    

     

    Donnerstag, 1. September 2011 18:27
  • Hallo,

    In dem Beispiel hatte ich den verkürzten Weg des Auflistungsinitialisierers gewählt, um ein Feature vorzustellen. 
    Dabei erstellt der Kompiler die notwendigen Befehle, um die Instanzen in die Liste einzufügen.
    Es ist identisch zu dem. wenn man jede Instanz einzeln erzeugen und mit Add zur Liste hinzufügen würde.

    Es ist also egal, wie und wann die Instanzen in die Liste reinkommen.

    Filtern und Sortieren kann man unabhängig davon.
    LINQ To Objects genügt bereits ein IEnumerable(T), was jedes Array
    und jede (generische) Standard-Auflistung bereitstellt.

    Unter 101 LINQ-Beispiele für Visual Basic findest Du verschiedene Anwendungsbeispiele.

    Falls Du Schwierigkeiten hast, das auf Deine Klassen / Auflistungen anzuwenden,
    poste einen Ausschnitt und die gewünschten Ergebnisse.

    Gruß Elmar

    Donnerstag, 1. September 2011 19:21
    Beantworter
  • Hallo Elmar,

    im folgenden Code habe ich meine abgewandelte Version. In der Anweisung "Dim dateien As New List(Of Datei)" (fett markiert) sagt mir der Debugger "Keine untergeordneten Elemente verfügbar".

    lg heinz

     

    Public Class Form1
      Dim zeiger As Datei
      Private Sub MeinInitial()
        zeiger = New Datei() With { _
          .KameraNr = "123", _
          .Dateiname = "C:\TEMP\Datei123.jpg", _
          .Änderungsdatum = Date.Parse("28.04.2011 03:23:15"), _
          .ListenName = "Liste 1", _
          .DateiGröße = 10000}
        zeiger = New Datei() With { _
         .KameraNr = "124", _
         .Dateiname = "C:\TEMP\Datei124.jpg", _
         .Änderungsdatum = Date.Parse("27.04.2011 12:20:15"), _
         .ListenName = "Liste 2", _
         .DateiGröße = 20000}
        zeiger = New Datei() With { _
          .KameraNr = "123", _
          .Dateiname = "C:\TEMP\Datei125.jpg", _
          .Änderungsdatum = Date.Parse("15.02.2011 23:03:57"), _
          .ListenName = "Liste 1", _
          .DateiGröße = 5000}
        zeiger = New Datei() With { _
          .KameraNr = "124", _
          .Dateiname = "C:\TEMP\Datei125.jpg", _
          .Änderungsdatum = Date.Parse("28.03.2011 01:49:03"), _
          .ListenName = "Liste 1", _
          .DateiGröße = 5000}
    
        Dim dateien As New List(Of Datei) 'HIER IST DER FEHLER
      End Sub
    
     
      Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        MeinInitial()
      End Sub
    End Class
    
    Public Class Datei
      Public Property KameraNr As String ' Integer ?
      Public Property Dateiname As String
      Public Property Änderungsdatum As Date
      Public Property ListenName As String
      Public Property DateiGröße As Long ' halbe Bytes gibt es nicht
    End Class

    Donnerstag, 1. September 2011 19:53
  • Hallo Heinz,

    bei der fett markieren Zeile kommt dieser Fehler eher nicht.

    Allerdings frage ich mich dennoch, was die Zeile an dieser Stelle bewirken soll?

    Schreib die an den Anfang der Methode und füge deine erzeugten Objekte auch per dateien.Add( zeiger ) in die Liste ein.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Donnerstag, 1. September 2011 21:16
    Moderator
  • Hallo Heinz,

    so wie Du es zeigst, kommen keine Daten (Dateien) in der Liste an.
    Du erzeugst zwar immer eine neue Instanz, weist sie jedoch immer der gleichen Variable zu, und fügst sie nie der Liste hinzu.

    Damit die dateien nach dem verlassen von MeinInitial zur Verfügung steht, müsste sie als Instanz-Variable deklariert werden.
    zeiger hingegen kann lokal in der Prozedur definiert werden, da sie nur zwischendurch den Verweis aufnimmt.
    Und man käme auch ganz ohne aus, wie man sehen sollte:

     
    ' Als Instanz / Klassenvarible
    Dim dateien As New List(Of Datei) 'HIER IST DER FEHLER
     
    Private Sub MeinInitial()
      ' Erstellen...
      Dim zeiger As New Datei() With { _
       .KameraNr = "123", _
       .Dateiname = "C:\TEMP\Datei123.jpg", _
       .Änderungsdatum = Date.Parse("28.04.2011 03:23:15"), _
       .ListenName = "Liste 1", _
       .DateiGröße = 10000}
       
       ' und in die Liste anfügen.
       dateien.Add(zeiger)
       
       ' weitere Instanz erzeugen
      zeiger = New Datei() With { _
       .KameraNr = "124", _
       .Dateiname = "C:\TEMP\Datei124.jpg", _
       .Änderungsdatum = Date.Parse("27.04.2011 12:20:15"), _
       .ListenName = "Liste 2", _
       .DateiGröße = 20000}
       
       ' und anfügen
       dateien.Add(zeiger)
      
      ' oder direkt anfügen
      dateien.Add(New Datei() With { _
       .KameraNr = "123", _
       .Dateiname = "C:\TEMP\Datei125.jpg", _
       .Änderungsdatum = Date.Parse("15.02.2011 23:03:57"), _
       .ListenName = "Liste 1", _
       .DateiGröße = 5000})
       
       dateien.Add(new Datei() With { _
       .KameraNr = "124", _
       .Dateiname = "C:\TEMP\Datei125.jpg", _
       .Änderungsdatum = Date.Parse("2a8.03.2011 01:49:03"), _
       .ListenName = "Liste 1", _
       .DateiGröße = 5000})
       
       ' sollte hier 4 ergeben
       Console.WriteLine("In Dateien sind {0} Elemente enthalten", dateien.Count)
    End Sub
    
    

    Nun kannst Du im weiteren Programmveraluf auf die Dateien zugreifen.
    Und wie im anderen Beispiel sortieren, filtern usw.

    Gruß Elmar

    • Als Antwort markiert Heinz999 Freitag, 2. September 2011 06:20
    Donnerstag, 1. September 2011 22:26
    Beantworter
  • Hallo Elmar,

    jetzt habe ich es begriffen,

    herzlichen Dank, Heinz

    Freitag, 2. September 2011 06:23