IEnumerator uninitialisiert

  • VB.NET
  • .NET (FX) 3.0–3.5

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    IEnumerator uninitialisiert

    Hallo Leute,

    ich hatte vor einer Woche nach dem Intel-8MB-Bug einen Totalverlust meiner Systemlaufwerks.
    Da ich dadurch auch meine ganzen Projekt-Datetein von VisualStudio verlor musste ich mich mit dem Gedanken anfreunden, viel neu zu schreiben.

    Allerdings viel mir dann ein Decompiler fuer .Net in die Hand, welcher eine echt grosse Hilfe ist, da er meinen Code zu einem überragenden Anteil 1:1 wiederherstellt.
    Denn das fertige Kompilat habe ich ja auf den NAS zu liegen.

    Da ich nur ein Amateur-Programmiere bin und ich viele Programmiertechniken nicht kenne, stellt mir der Decompiler in einer Subroutine Code wieder her, bei dem ich nicht alles verstehe.

    Ziel der Sub ist es, das Textboxen eine neue Hintergrundfarbe zugewiesen wird.
    Dazu durchlaufe ich alle Controls in Panel1 und Panel2, und wenn das Control mit dem Namen, dem ich der Sub übergeben habe gefunden wurde, wird diesem eine neue Hintergrundfarbe verpasst.

    VB.NET-Quellcode

    1. Private Sub paint_textboxes_green(ByVal tbname As String)
    2. Dim current As Control
    3. Dim box As TextBox
    4. Dim enumerator As IEnumerator
    5. Dim enumerator2 As IEnumerator
    6. Try
    7. enumerator = Me.Panel1.Controls.GetEnumerator
    8. Do While enumerator.MoveNext
    9. current = DirectCast(enumerator.Current, Control)
    10. If (current.GetType Is GetType(TextBox)) Then
    11. box = DirectCast(current, TextBox)
    12. If (box.Name = tbname) Then
    13. box.BackColor = Color.LimeGreen
    14. End If
    15. End If
    16. Loop
    17. Finally
    18. If TypeOf enumerator Is IDisposable Then
    19. TryCast(enumerator, IDisposable).Dispose()
    20. End If
    21. End Try
    22. Try
    23. enumerator2 = Me.Panel2.Controls.GetEnumerator
    24. Do While enumerator2.MoveNext
    25. current = DirectCast(enumerator2.Current, Control)
    26. If (current.GetType Is GetType(TextBox)) Then
    27. box = DirectCast(current, TextBox)
    28. If (box.Name = tbname) Then
    29. box.BackColor = Color.LimeGreen
    30. End If
    31. End If
    32. Loop
    33. Finally
    34. If TypeOf enumerator2 Is IDisposable Then
    35. TryCast(enumerator2, IDisposable).Dispose()
    36. End If
    37. End Try
    38. End Sub


    Der Code funktioniert soweit.
    Nur bekomme ich zwei Warnungen, dass enumerator und enumerator2, bevor denen ein Wert zugewiesen wird, benutzt werden.

    Kann ich bei der Dimensionierung des IEnumerator diesem einem "Grundwert" zuweisen, wie ich das beim Strings machen würde?
    Sowas in der Form von

    VB.NET-Quellcode

    1. Dim foo As String() = New String(19) {}
    2. 'bzw.:
    3. Dim bar As UInt16 = 432623


    Danke schonmal für eure Hilfe!
    Hi
    wenn GetEnumerator fehlschlägt, ist es im Finally-Block ungesetzt. Daher die Warnung. Eine Dimensionierung des IEnumerators kannst du nicht vornehmen, da der lediglich die zugrundeliegende Liste durchgeht.
    Übrigens könntest du das, was du da gemacht hast, auch als For-Schleife modellieren. Außerdem macht TryCast das TypeOf überflüssig:

    VB.NET-Quellcode

    1. Dim x As IDisposable = TryCast(y, IDisposable)
    2. If x IsNot Nothing Then x.Dispose()



    Viele Grüße
    ~blaze~
    kannst bei der Deklaration Nothing zuweisen, dann geht die Meldung weg.

    Ansonsten scheint der Decompiler eine ForEach-Schleife nicht zu kennen, weil was er da umständlich formuliert wäre einfach so:

    VB.NET-Quellcode

    1. Private Sub paint_textboxes_green(ByVal tbname As String)
    2. For Each ctl As Control In Panel1.Controls
    3. Dim box = TryCast(ctl, TextBox)
    4. If box IsNot Nothing AndAlso box.Name = tbname Then box.BackColor = Color.LimeGreen
    5. Next
    6. For Each ctl As Control In Panel2.Controls
    7. Dim box = TryCast(ctl, TextBox)
    8. If box IsNot Nothing AndAlso box.Name = tbname Then box.BackColor = Color.LimeGreen
    9. Next
    10. End Sub
    11. 'oder noch eleganter
    12. Private Sub paint_textboxes_green2(ByVal tbname As String)
    13. For Each pnl In {Panel1, Panel2}
    14. For Each box In pnl.Controls.OfType(Of TextBox)()
    15. If box.Name = tbname Then box.BackColor = Color.LimeGreen
    16. Next
    17. Next
    18. End Sub


    @blaze: Es ist kein TryCatch, sondern nur ein TryFinally!
    Danke ihr zwei.

    Meine anfangs verwendete Möglichkeit, die Hintergrundfarbe zu ändern hatte ich seinerzeits auf StackExchange gefunden.
    Es verrichtete seinen Dienst - das reichte mir. Ich stellte somit meine weitere Suche nach einer Möglichkeit, alle Steuerelemente zu durchlaufen und zu schauen, ob das gesuchte daei ist, ein.

    Die kleine for-Schleife (Zeile 13-19) von ErfinderDesRad ist natürlich um einiges schöner.
    Allein, weil ich sie auf Anhieb verstehe ;)

    Das ich damals keine Warnung bekam, mag vielleicht auch daran liegen, dass ich mittlerweile mit 'Option Strict on' programmiere.
    Der Code, den ich "wiederhergestellt" habe, war noch mit den Standard-Einstellung von VisualStudio2010 programmiert.

    Nochmals danke!
    Nochmals Danke an ErfinderDesRades ...

    mit der zweiten Schleife konnte ich nun auch aus meinen aktuell drei Funktionen (für grün, gelb und rot) eine einzige machen.

    VB.NET-Quellcode

    1. Private Sub paint_textboxes(ByVal tbname As String, ByVal colorcode As Byte)
    2. Dim tbcolor As Color = Color.Black
    3. Select Case colorcode
    4. Case 1 : tbcolor = Color.LimeGreen
    5. Case 2 : tbcolor = Color.Yellow
    6. Case 3 : tbcolor = Color.Red
    7. End Select
    8. For Each pnl In {Panel1, Panel2}
    9. For Each box In pnl.Controls.OfType(Of TextBox)()
    10. If box.Name = tbname Then box.BackColor = tbcolor
    11. Next
    12. Next
    13. End Sub


    Das vereinfacht die Lesbarkeit meines Codes ungemein.
    Findich gut, wie du deinen Code auf Verständlichkeit optimierst. :thumbsup:
    Verständlichkeit ist (nach Funktions-Korrektheit) die mit (Riesen-)Abstand wichtigste Dimension, nach der man sein Coden ausrichten sollte, und heißt in Umsetzung meist: Einfachheit und Kürze.
    Üblicherweise ist der verständlichste Code auch gleichzeitig der resourcen- und performance- effizienteste, zumindest annähernd, sodass weitere Optimierung nur noch Peanuts brächte.
    Hier noch Vorschlag, die Kürze weiter auf Spitze zu treiben:

    VB.NET-Quellcode

    1. Private _Colors As Color() = New Color() {Color.Black, Color.LimeGreen, Color.Yellow, Color.Red}
    2. Private Sub paint_textboxes(ByVal tbname As String, ByVal colorcode As Integer)
    3. If colorcode >= _Colors.Length Then colorcode = 0 'Korrektur ungültiger colorcodes
    4. For Each pnl In {Panel1, Panel2}
    5. For Each box In pnl.Controls.OfType(Of TextBox)()
    6. If box.Name = tbname Then box.BackColor = _Colors(colorcode)
    7. Next
    8. Next
    9. End Sub
    Wäre sogar empfehlenswert, die Korrektur wegzulassen, um eine Exception gemeldet zu bekommen, wenn die Methode mit ungültigem colorCode aufgerufen wird.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()