none
For Each Schleife mit Objekt hinzufügen RRS feed

  • Frage

  • Hallo Forum,

    ich habe eine For Each Schleife in der ich Objekte in diese Aufzählung einfüge. Nach dem Einfügen eines Objektes steigt der Debugger beim Next oder For Each aus.

    Ich habe gelesen dass dies normal ist, aber durch eine Einstellung im "iEnumerable" denoch möglich ist. Leider finde ich keine Beschreibung darüber. Ich hoffe ihr könnt mir helfen.

    Nachstehen der Code-Ausschnitt (die Abbruchzeilen sind fett):

    lg heinz

    Public Class Form1
        '
        '   Beschreibt die Eigenschaften einer Station (Standort)
        Structure StructStationen
            Public Property nr As Integer                   'Stationsnr
            Public Property verkehrsmittel As Integer       'hat hier eine Haltestelle
            Public Property nach As Integer                 'fährt nach Station (0 ist keine Verbindung)
        End Structure
        '
        Dim stationen As New List(Of StructStationen)
        '
        '   Beschreibung der Eigenschaften einer Wegstrecke (von Station zu Station)
        Structure StructWege
            Public Property zugNr As Integer                'Zugnummer nach ...
            Public Property station As Integer              'Position
            Public Property vorgaenger As Integer           'Position des Vorgänger
            Public Property vorgaengerVM As Integer         'Verkehrsmittel von Vorgänger zum Standort
            Public Property nachfolger As Integer           'Position des Nachfolgers
            Public Property nachvolgerVM As Integer         'Verkehrsmittel vom Standort zum Nachfolger
        End Structure
        '   Auflistung aller möglichen Wegestrecken
        Dim wege As New List(Of StructWege)
        Dim wegeSelektiert As IEnumerable(Of StructWege)
        '
        '   Variablen
         Dim spielerPosition() As Int16 = {0, 0, 0, 0}
    
        '------------------------------------------------------------------------------------------
         '
        '   Mögliche Wege für nächsten Zug suchen und speichern
        Private Sub ErstelleMöglicheWege(ByVal zugNr As Int16, ByVal vm As Int16)
                   '   Alle möglichen Wege des Zuges selektieren
            Dim moeglicheWege = From d In wege
                                Where (d.zugNr = zugNr)
                                Select d
            '   Für jeden Weg-Endpunkt die Weiterreise anhand des Verkehrsmittel prüfen
            For Each item In moeglicheWege
                '   betroffene Station selektieren
                Dim st As Int16 = item.station
                Dim station = From b In stationen
                              Where b.nr = st
                              Select b
                '   Station auf weiteren Weg und Verkehrsmittel prüfen
                For Each stat In station
                    If stat.nach > 0 And stat.verkehrsmittel = vm Then
                        '   Station auf besetzt prüfen
                        If PruefeObBesetzt(stat.nach) Then
                            '   neuen möglichen Weg speichern
                            StartWegeErstellen(zugNr + 1, stat.nach, st, 0, 0, 0)
                        End If
    
                    End If
                Next
            Next
        End Sub
        '
        '    Wege erstellen
        Private Sub StartWegeErstellen(ByVal zugNr As Int16, ByVal station As Int16, ByVal vorgaenger As Int16, _
                                       ByVal vorgaengerVM As Int16, ByVal nachfolger As Int16, _
                                       ByVal nachvolgerVM As Int16)
    
            wege.Add(New StructWege() With { _
                .zugNr = zugNr, _
                .station = station, _
                .vorgaenger = vorgaenger, _
                .vorgaengerVM = vorgaengerVM, _
                .nachfolger = nachfolger, _
                .nachvolgerVM = nachvolgerVM})
        End Sub
         '
        '   Prüfen ob Station von einen Spieler besetzt
        Private Function PruefeObBesetzt(ByVal stat As Int16) As Boolean
            PruefeObBesetzt = True
            For i As Int16 = 0 To spielerPosition.Length - 1
                If spielerPosition(i) = stat Then PruefeObBesetzt = False
            Next
        End Function
    
    
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            StartWegeErstellen(1, 7, 0, 0, 0, 0)
            StationenEinlesen()
            ErstelleMöglicheWege(1, 1)
        End Sub
    End Class
    

    Sonntag, 4. September 2011 13:23

Antworten

  • Damit liegst du richtig. Wenn du das einfach zuweist, wirds neur ne Referenz auf das alte Objekt...

    Du musst neuWege musst du wirklich neu erzeugen.

    • Als Antwort markiert Heinz999 Montag, 5. September 2011 10:28
    Sonntag, 4. September 2011 20:43
  • Das heißt Objekt für Objekt von Original zur Kopie kopieren?

    Und nach dem Durchlauf wieder Objekt für Objekt von Kopie zum Original? (natürlich vorher Clear)

    Zu 1: Ja.

    Zu 2: Nein. Da reicht es, wenn Du nach der Schleife entweder:

      Original = Kopie

    oder:

      Original.Clear()
      Original.AddRange( Kopie )

    schreibst.

     


    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
    • Als Antwort markiert Heinz999 Montag, 5. September 2011 10:27
    Montag, 5. September 2011 09:56
    Moderator

Alle Antworten

  • Hi,

    ich habe eine For Each Schleife in der ich Objekte in diese Aufzählung einfüge. Nach dem Einfügen eines Objektes steigt der Debugger beim Next oder For Each aus.

    Ich habe gelesen dass dies normal ist, aber durch eine Einstellung im "iEnumerable" denoch möglich ist. Leider finde ich keine Beschreibung darüber. Ich hoffe ihr könnt mir helfen.

    ich kann dir da nur insoweit helfen, dass ich dir die Empfehlung gebe, eben nicht während einer Autobahnfahrt die Räder zu tauschen. Es gibt zwar sogar Leute, die das können aber das dürften nur sehr, sehr weniger Spezialisten sein :)

    Soll heißen: Ändere nicht die Auflistung, die Du gerade durchläufst, das macht keinerlei Sinn. Erstell dir eine neue Auflistung und füge die Objekte dort 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
    Sonntag, 4. September 2011 17:08
    Moderator
  • Wie schon gesagt - du kannst keine Auflistung während einer Iteration über die Elemente verändern.

    Was geht:

    hol die den Enumerator und iteriere "per Hand" - also in einer While Schleife über die Elemente.

    Den Iterator musst du allerdings dann neu holen, wenn du ein Item hinzufügst. Damit würde die Schleife dann allerdings wieder von vorne beginnen - nicht grad performant aber vielleicht machbar. Wenn du allerdings in jedem Iterationsschritt was änderst macht es sehr viel Sinn die Daten in einer zweiten Collection hinzuzuführen, wir der Kollege bereits vorgeschlagen hat.

    Viel Spass

    Sonntag, 4. September 2011 17:26
  • Hallo Stefan,

    habe ich probiert: neuWege = aktWege, dann habe ich aktWege durchlaufen und bei neuWege neue Objekte hinzugefügt. Hat auch nicht funktioniert (vielleicht ist die Kopie nur ein Verweis auf das Original?).

    lg heinz

     

    Sonntag, 4. September 2011 19:51
  • Damit liegst du richtig. Wenn du das einfach zuweist, wirds neur ne Referenz auf das alte Objekt...

    Du musst neuWege musst du wirklich neu erzeugen.

    • Als Antwort markiert Heinz999 Montag, 5. September 2011 10:28
    Sonntag, 4. September 2011 20:43
  • Das heißt Objekt für Objekt von Original zur Kopie kopieren?

    Und nach dem Durchlauf wieder Objekt für Objekt von Kopie zum Original? (natürlich vorher Clear)

    lg heinz

    Sonntag, 4. September 2011 20:51
  • Das heißt Objekt für Objekt von Original zur Kopie kopieren?

    Und nach dem Durchlauf wieder Objekt für Objekt von Kopie zum Original? (natürlich vorher Clear)

    Zu 1: Ja.

    Zu 2: Nein. Da reicht es, wenn Du nach der Schleife entweder:

      Original = Kopie

    oder:

      Original.Clear()
      Original.AddRange( Kopie )

    schreibst.

     


    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
    • Als Antwort markiert Heinz999 Montag, 5. September 2011 10:27
    Montag, 5. September 2011 09:56
    Moderator
  • Danke, das hat geholfen,

    lg heinz

    Montag, 5. September 2011 10:29