InvalidCastException beheben?

  • VB.NET

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von ThePlexian.

    InvalidCastException beheben?

    Hi, wollte für Physik ein Programm schreiben, dass mir die Methode der kleinen Schritte ausführt und Geschwindigkeit, Beschleunigung, etc. zu einem bestimmten Zeitpunkt widergibt.
    Jetzt hab ich nur das Problem, dass ich bei Zeile 35 (x1 = x0 + ...) den Fehler bekomme:

    "InvalidCastException wurde nicht behandelt. Ungültige Konvertierung von der Zeichenfolge 0,8972024159251,10733060732316 in Typ Double."

    Mir ist bewusst, dass ich noch der volle Anfänger bin und man das evtl. auch besser hätte schreiben können, aber so hab ichs nunmal gemacht.
    Wäre für eine Lösung echt dankbar :)

    David

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim y As String
    3. Dim z As Integer
    4. Dim t0 As String = "0"
    5. Dim v0 As String = "0"
    6. Dim x0 As String = "0"
    7. Dim a0 As String = "9,81"
    8. Dim t1 As String
    9. Dim v1 As String
    10. Dim x1 As String
    11. Dim a1 As String
    12. Dim deltaT As String = "0,05"
    13. Dim g As String = "9,81"
    14. Dim k As String
    15. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    16. Cw.Text = "0,9"
    17. Fläche.Text = "0,2"
    18. Masse.Text = "60"
    19. Dichte.Text = "1,29"
    20. Zeit.Text = "0,1"
    21. y = Zeit.Text
    22. z = y / deltaT
    23. k = (Cw.Text * Fläche.Text * Dichte.Text) / 2 * Masse.Text
    24. Dim w As String = z
    25. ZA.Text = z
    26. Do Until z = 0
    27. t1 = t0 + deltaT
    28. v1 = v0 + a0 * deltaT
    29. x1 = x0 + 0.5 * (v0 + v1) * deltaT
    30. a1 = g - k * v1 * v1
    31. t0 = t1 + deltaT
    32. v0 = v1 + a1 * deltaT
    33. x0 = x1 + 0.5 * (v0 * v1) * deltaT
    34. a0 = g - k * v0 * v0
    35. z = z - 1
    36. Loop
    37. If Not (w - Int(w)) > 0 Then
    38. tNeu.Text = t1
    39. vNeu.Text = v1
    40. xNeu.Text = x1
    41. aNeu.Text = a1
    42. End If
    43. End Sub
    44. End Class

    Veloiraptor45 schrieb:

    Dim t0 As String = "0"
    Dim v0 As String = "0"
    Dim x0 As String = "0"
    Dim a0 As String = "9,81"
    Dim t1 As String
    Dim v1 As String
    Dim x1 As String
    Dim a1 As String
    Dim deltaT As String = "0,05"
    Dim g As String = "9,81"
    Dim k As String
    Nicht alles ist ein String, vor allem Zahlen nicht, dennoch speicherst du sie als String. Damit trittst du natürlich direkt ins Fettnäpfchen, da "+" nur bei Zahlen Addition durchführt, Strings werden damit aneinandergehängt (wie sollte man auch mit nem Text rechnen?). Schalte zunächst Option Strict auf On und ändere dann die Datentypen von String in einen angemessenen, Double oder Decimal.

    Veloiraptor45 schrieb:

    VB.NET-Quellcode

    1. Dim g As String = "9,81"
    Das sollte heißen

    VB.NET-Quellcode

    1. Dim g As Double = 9.81
    Trenne GUI von Datzen. Rechne mit Daten, zeige Ergebnisse an.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Parse oder TryParse ist das Schlüsselwort auf dem Weg zur Lösung.

    VB.NET-Quellcode

    1. Dim masse As Double = Double.Parse(txtMasse.Text)
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Hab das ganze jetzt mal überarbeitet, bekomme aber beim Debuggen diesen Fehler: "Fehler beim Erstellen des Formulars. Weitere Informationen finden Sie in Exception.InnerException. Fehler: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.." und kann beim besten Willen nichts damit anfangen, weil vorallem keine Zeile bei Form1.vb markiert ist und dieses Fenster (siehe Anhang) aufgeht.

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class Form1
    3. Dim y As Double = Double.Parse(Zeit.Text)
    4. Dim z As Double = 0
    5. Dim t0 As Double = 0
    6. Dim v0 As Double = 0
    7. Dim x0 As Double = 0
    8. Dim a0 As Double = 9.81
    9. Dim t1 As Double = 0
    10. Dim v1 As Double = 0
    11. Dim x1 As Double = 0
    12. Dim a1 As Double = 0
    13. Dim deltaT As Double = 0.5
    14. Dim g As Double = 9.81
    15. Dim k As Double = 0
    16. Dim Zeit1 As Double = Double.Parse(Zeit.Text)
    17. Dim Masse1 As Double = Double.Parse(Masse.Text)
    18. Dim Cw1 As Double = Double.Parse(Cw.Text)
    19. Dim Fläche1 As Double = Double.Parse(Fläche.Text)
    20. Dim Dichte1 As Double = Double.Parse(Dichte.Text)
    21. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    22. Cw.Text = "0.9"
    23. Fläche.Text = "0.2"
    24. Masse.Text = "60"
    25. Dichte.Text = "1.29"
    26. Zeit.Text = "0.1"
    27. z = y / deltaT
    28. k = (Cw1 * Fläche1 * Dichte1) / 2 * Masse1
    29. Dim w As Double = z
    30. Dim s As String = z.ToString()
    31. ZA.Text = s
    32. Do Until z = 0
    33. t1 = t0 + deltaT
    34. v1 = v0 + a0 * deltaT
    35. x1 = x0 + 0.5 * (v0 + v1) * deltaT
    36. a1 = g - k * v1 * v1
    37. t0 = t1 + deltaT
    38. v0 = v1 + a1 * deltaT
    39. x0 = x1 + 0.5 * (v0 * v1) * deltaT
    40. a0 = g - k * v0 * v0
    41. z = z - 1
    42. Loop
    43. If Not (w - Int(w)) > 0 Then
    44. Dim t2 As String = t1.ToString
    45. tNeu.Text = t2
    46. Dim v2 As String = v1.ToString
    47. vNeu.Text = v2
    48. Dim x2 As String = x1.ToString
    49. xNeu.Text = x2
    50. Dim a2 As String = x1.ToString
    51. aNeu.Text = a2
    52. End If
    53. End Sub
    54. End Class
    Bilder
    • MdkS Fehler.png

      89,61 kB, 1.919×938, 131 mal angesehen
    Das

    Veloiraptor45 schrieb:

    Dim Zeit1 As Double = Double.Parse(Zeit.Text)
    Dim Masse1 As Double = Double.Parse(Masse.Text)
    Dim Cw1 As Double = Double.Parse(Cw.Text)
    Dim Fläche1 As Double = Double.Parse(Fläche.Text)
    Dim Dichte1 As Double = Double.Parse(Dichte.Text)
    kann nicht funktionieren, weil Initialisierungswerte auf Klassenebene vor dem Konstruktor aufgerufen werden, die Steuerelemente werden aber erst dort erstellt (bzw. in InitializeComponent, was im Konstruktor aufgerufen wird). Du kannst die Werte erst festlegen, wenn die Steuerelemente erstellt wurden, und etwas gültiges darin steht, ansonsten gibts wieder Fehler.

    Veloiraptor45 schrieb:

    Hätte ich ja auch irgendwie selbst drauf kommen können.
    Wüsste nicht wie.
    Für erste Geh-Versuche ist dein Code, und besonders die Umsetzung der Lösungs-Hinweise, hervorragend! :thumbsup:

    Und wenn ich recht verstanden habe, hast du nun sogar bereits verstanden, was InitializeComponents macht, und warum man erst danach auf Steuerelemente zugreifen kann.
    @Veloiraptor45:: Das hast Du noch nicht ganz umgesetzt:

    RodFromGermany schrieb:

    Trenne GUI von Datzen. Rechne mit Daten, zeige Ergebnisse an.
    Startwerte sind Daten, die initial zugewiesen werden.
    Weise alle Werte zu, auch, wenn da 0 drin steht. Mach Dir eine Routine, die alle Werte aus den Daten-Elementen an die GUI bringt:

    VB.NET-Quellcode

    1. Private Sub ActualizeGui()
    2. Zeit.Text = Zeit1.ToString
    3. Masse.Text = Masse1.ToString
    4. ' usw.
    5. End Sub

    Statt Dim Zeit1 As Double = Double.Parse(Zeit.Text) machst Du Dim Zeit1 As Double = 1.25 ' Initialwert, Deiner natürlich
    Und in der Form_Load rufst Du einfach ActualizeGui() auf. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Weiß nicht, ob
    Dim Zeit1 As Double = 1.25
    so sinnvoll ist. Du kannst das aus dem Code nicht rauslesen, aber

    VB.NET-Quellcode

    1. Cw.Text = "0.9"
    2. Fläche.Text = "0.2"
    3. Masse.Text = "60"
    4. Dichte.Text = "1.29"
    5. Zeit.Text = "0.05"
    kommt später raus, will ja die Daten selbst in die Textboxen eingeben und auslesen und keine vordefinierten Werte haben. Dann bräuchte ich das Programm ja nicht. Das habe ich jetzt nur gemacht, damit ich bei nem Testlauf nich immer die Werte eingeben muss.

    Und ich hab da was nich verstanden:
    Was bring mir das:

    VB.NET-Quellcode

    1. Private Sub ActualizeGui()
    2. Zeit.Text = Zeit1.ToString
    3. Masse.Text = Masse1.ToString
    4. ' usw.
    5. End Sub

    Sprich, was bring mir das, wenn die Daten aus den Textboxen in Strings umgewandelt werden? Ich will mit denen ja rechnen...

    David
    Das ist erforderlich. Eine zahl kann nicht angezeigt werden, denn ne zahl ist lediglich ein Speicherzustand in deinem Computer. Tatsächlich verhält sich das mit allem, was nicht String ist, so, einzig Strings können tatsächlich angezeigt werden. Deshalb musst du, wenn du etwas anzeigen willst, in die entsprechende Stringrepräsentation umwandeln. Es hört sich aber komplizierter an, als es ist. Alle Zahlentypen haben eine überschriebene ToString-Funktion, und z.B. 9.81 wird einfach zu "9.81", also nichts, worüber man sich Sorgen machen müsste. Man bekommt sogar Vorteile dadurch. Du könntest z.B. eine Zahl Hexadezimal anzeigen wollen. An der zahl an sich ändert sich dadurch nix, du gibst nur an, dass du den String in Hex haben möchtest, und schon ist es Hex.
    Oder nochmal mit anderen Worten: Mit deinen Textboxen willst du in deinem Programm gar nix machen. Und schon gar nicht rechnen. Die sind einzig und allein als Schnittstelle gedacht zwischen deinem Programm und dessen Benutzer. Das heitßt: Die TextBox ist dazu da, dass der Benutzer hier Werte eingeben kann, mit denen dein Programm rechnen soll, und in diesem speziellen Fall sind sie wohl auch dazu da, um das Ergebnis der Berechnung dem Benutzer wieder visuell zugänglich zu machen (sprich: anzuzeigen).

    Intern hantierst du grundsätzlich mit numerischen Variablen (also Single oder Double oder Integer oder...). Was du nur zusätzlich machen musst, ist dafür zu sorgen, dass die Übergänge - also die Schnittstelle - zwischen Benutzer (TextBoxen) und Berechnungslogik (Double-Variablen) ausprogrammiert werden und an den richtigen Stellen aufgerufen werden.

    Das heißt:

    1. Soll die Berechnung gestartet werden (z.B. indem der Benutzer einen Button aklickt), liest du die Texte aus den TextBoxen aus, konvertierst sie ihn Zahlenwerte und speicherst das Ergebnis in deinen Variablen.

    2. Dann führst du deine eigentliche Berechnungslogik durch.

    3. Am Ende - also wenn das Ergebnis der Berechnung(en) feststeht, müssen die Ergebnisse wieder dargestellt werden, d.h. du nimmst deine numerischen Variablen, erzeugst daraus eine Zeichenfolgen-Repräsentation (z.B. mit ToString()) und diese resultierenden Strings kannst du dann wieder der Text-Eigenschaft deiner TextBoxen zuweisen.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Danke an alle bisher, Programm is zu 99% fertig. Eine Frage noch: gib es einen Reset-Befehl für Variablen? Also, dass die nach dem Befehl ihren Anfangswert wieder haben oder muss ich, nachdem das Programm durchgelauften ist, den Variablen selbst die Anfangswerte wieder zuweisen, also:

    VB.NET-Quellcode

    1. t0=0
    2. v0=0
    3. x0=0 ...
    Hab bisher leider bloß Reset-Befehle für Textboxen gefunden.

    Veloiraptor45 schrieb:

    gib es einen Reset-Befehl für Variablen?
    Nein.
    Mach Dir eine Prozedur (Sub), in der Du alle erforderlichen Variablen initialisierst.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Veloiraptor45 schrieb:


    VB.NET-Quellcode

    1. Do Until z = 0
    2. t1 = t0 + deltaT
    3. v1 = v0 + a0 * deltaT
    4. x1 = x0 + 0.5 * (v0 + v1) * deltaT
    5. a1 = g - k * v1 * v1
    6. t0 = t1 + deltaT
    7. v0 = v1 + a1 * deltaT
    8. x0 = x1 + 0.5 * (v0 * v1) * deltaT
    9. a0 = g - k * v0 * v0
    10. z = z - 1
    11. Loop

    Ich weiß ja nicht was das für eine physikalische Formel ist, aber meinste nicht, dass das iwie einfacher ohne Do-Loop geht (ggf. Potenzen) ?

    Edit: Außerdem ist dein z ja nur eine Zählvariable, ist also genau das gleiche wie:

    VB.NET-Quellcode

    1. For z As Interger = [Startwert] To 0 Step -1
    2. 'Code
    3. Next
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais