Strict on - Die ersten Versuche.

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 67 Antworten in diesem Thema. Der letzte Beitrag () ist von woeh.

    Mach aus den Verweisen den importierten Microsoft.VisualBasic-Namespace (ist wohl für VB6-Kompatibilität gemacht worden) raus und sieh, was passiert. Ok, das gibt dann wohl nochmal 300 weitere Fehler, daher verschieb das ganze auf später.
    => InStr, Mid, Left und Co sind noch aus VB6-Zeiten; IndexOf, Substring etc. sind moderne .Net-Varianten und daher bevorzugt zu verwenden. Wir wollen doch nicht mit veralteten, verrosteten Werkzeugen arbeiten, gelle?
    Ob ein inhaltlicher Unterschied besteht, weiß wohl nur Mikrosaft. Würde mich nicht wundern, wenn es nur Wrapper sind, also dass sie die .Net-Varianten selber aufrufen und wirklich nur eine Brücke zwischen alter VB6-Welt und .Net-Welt darstellen sollen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hab nochmal eins nachgesetzt (s.o.): Kompatibilität.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Es wird tatsächlich Arbeit, aber nicht schwieriger. So wird halt z.B. Left zu Remove, Mid zu Substring(startIndex, length) und Right zu Substring(startIndex) oder InStr zu IndexOf.

    Der mMn. springende Punkt ist aber eigentlich nicht die Kompatibilität, sondern vielmehr, dass es gegen die objektorientierte Programmierung geht. In der OOP arbeitet man auf Objekten, d.h. links steht ein Objekt, auf dem gearbeitet werden soll oder es ist implizit gegeben (--> Me.Bla() -> Bla()).
    Left, usw. sind nicht auf Objekten definiert, sondern quasi global erreichbare Methoden, da sie in VB-Modulen liegen und VB.Net diese dann entsprechend ohne Angabe des enthaltenden Modulnamen ansprechen lässt. Sonst müsste man immer Strings.Left, Strings.Mid, usw. schreiben. Die Objektorientierung arbeitet insofern auch nicht auf den statischen Methoden von Typen, sondern direkt auf den Objekten, was 1. intuitiver ist, da man immer eine Zusammengehörigkeit zwischen Methode und Klasse erkennen kann und weitaus übersichtlicher ist. Man stelle sich vor, alles wäre in Modulen, dann hätte man einen Sumpf von hunderten von Methoden, die alle von überall aus erreichbar sind, sobald der enthaltende Namensraum importiert wird.

    An sich solltest du auf jeden Fall behalten: Jede Methode aus dem Microsoft.VisualBasic-Namensraum lässt sich ersetzen (ebenso auch die Sachen aus My ersetzen, wozu dir viele Leute raten würden, abgesehen von My.Resources und My.Settings) und man sollte dies der Übersichtlichkeit halber auch tun.
    CBool, CSByte, CByte, CShort, CUShort, CInt, CUInt, CLng, CULng, CSng, CDbl, Chr und Asc würde ich ebenfalls verwenden, aber da gehen die Meinungen auseinander (insbesondere bei den letzten beiden). CStr und CChar würde ich nicht verwenden, da die nicht auf den primitiven Datentypen arbeiten. CInt, usw. würde ich auch nur zwischen den primitiven Datentypen verwenden. Diese sind Boolean, SByte, Byte, Short, UShort, Integer, UInteger, Long, ULong, Single, Double, Char. Ansonsten würde ich auf CType zurückgreifen (Decimal wäre noch ggf. eine Ausnahme); die Verwendung von diesem stattdessen ist aber eine persönliche Präferenz. Die primitiven Datentypen werden intern anders gehandhabt, als eigene Typen, daher die Entscheidung.

    Viele Grüße
    ~blaze~
    ok...so habe ich es kapiert...danke :)

    ich habe inzwischen mehr fehler...da taglib nicht unter strict on so funktioniert wie unter strict off.
    ich muß wieder einiges umschreiben....

    gut ding will eben weile haben...

    aber ich habe mir das nun mal in den kopf gesetzt....also wirds durchgezogen ;)

    ich habe ein ziemliches problem...
    es hat lange gedauert bis ich rausbekommen habe wie Taglib nur ID3v1 oder ID3v2 schreibt.
    ich möchte endlich die seperate klasse für ID3v1 rausscheiben...aber da gibts ein problem.

    also....ich fange mal an:

    so sieht die deklaration aus:

    VB.NET-Quellcode

    1. Dim ID3v1 As TagLib.Tag
    2. Dim ID3v2 As TagLib.Tag
    3. Dim mp3v1 As TagLib.File
    4. Dim mp3v2 As TagLib.File


    ich lesen ID3v1 und ID3v2 mit folgenden:

    VB.NET-Quellcode

    1. ID3v1GetTag(file, mp3v1, ID3v1)
    2. ID3v2GetTag(file, mp3v2, ID3v2)


    die funktion sieht wie folgt aus (ich nehme jetzt nur eine funktion, da sie sich ähneln):

    VB.NET-Quellcode

    1. Public Function ID3v1GetTag(ByVal file As IO.FileInfo,
    2. ByRef mp3 As TagLib.File,
    3. ByRef tag As TagLib.Tag,
    4. Optional testTag As Boolean = True) _
    5. As Boolean
    6. Dim hasID3v1 As Boolean
    7. If testTag Then
    8. hasTag(file, hasID3v1, False, False)
    9. Else
    10. hasID3v1 = True
    11. End If
    12. Try
    13. mp3 = TagLib.File.Create(file.FullName)
    14. tag = mp3.GetTag(TagLib.TagTypes.Id3v1)
    15. mp3.RemoveTags(mp3.TagTypes.Id3v2 And Not mp3.TagTypesOnDisk)
    16. If hasID3v1 = False Then
    17. ID3ClearTag(tag)
    18. End If
    19. Return True
    20. Catch ex As Exception
    21. Log(LogColor.errorInfo, Err.Description, Err.Number, file.FullName)
    22. End Try
    23. Return False
    24. End Function


    jetzt setzte ich die attribute fir ID3v1 und ID3v2...funktioniert alles.

    dann schreibe ich die datei wieder mit folgenden:

    VB.NET-Quellcode

    1. If chkTagEditorWriteID3v1.Checked = True Then
    2. ID3v1SaveTag(mp3v1)
    3. End If
    4. If chkTagEditorWriteID3v2.Checked = True Then
    5. ID3v2SaveTag(mp3v2)
    6. extraGenreCheck(ID3v2.FirstGenre)
    7. End If


    die funktion sieht wie folgt aus...(ich nehme wieder nur eine, da sie sich ähneln:

    VB.NET-Quellcode

    1. Public Function ID3v1SaveTag(ByVal mp3 As TagLib.File,
    2. Optional ByVal displayInfo As Boolean = True) _
    3. As Boolean
    4. Try
    5. mp3.RemoveTags(mp3.TagTypes.Id3v2 And Not mp3.TagTypesOnDisk)
    6. mp3.Save()
    7. If displayInfo = True Then
    8. Log(LogColor.fileInfo, "ID3v1Tag gespeichert",, mp3.Name)
    9. End If
    10. Return True
    11. Catch ex As Exception
    12. Log(LogColor.errorInfo, Err.Description, Err.Number, mp3.Name,,, False)
    13. Return False
    14. End Try
    15. End Function



    das problem ist, das wenn ich beide hintereinander schreibe nur der ersten tag geschrieben wird...also den ID3v1
    ID3v2 schreibt er nicht...

    schreibe ich einzeln, schreibt er richtig...aber nicht beide hintereinander.

    was mache ich falsch ?

    ich will endlich die seperate klasse für ID3v1 raus bekommen.....deshalb der ganze aufstand.

    oder ist es so, das taglib immer nur eine datei bearbeiten kann...also ich gar nicht 2 dateien öffnen kann ?
    ich habe keine ahnung....

    hilfe....bitte

    ich schätze mal, dass das 2te schreiben den tag vom ersten tag mitschreibt, obwohl ich das beim lesen des tags unterbunden habe.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „woeh“ ()

    Erst mal kleine Anmerkungen:
    - Sicher, dass es hinreichend ist, da Log aufzurufen und du nichts aufräumen musst, falls der Catch-Block erreicht wird? Bspw. Schließung von Files, Rückgängig-Machen der getätigten Einstellungen, usw.? Und hat die Bibliothek tatsächlich den Aufruf dieser ID3ClearTag-Methode nötig?
    - Statt If ... = True Then schreibt man idR. nur If ... Then, analog für If ... = False Then eben If Not ... Then
    - Im Catch-Block fängt man in den meisten Fällen spezifische Exceptions (Ausnahme bilden z.B. Rethrowing über das alleinstehende Throw-Statement oder spezielle Fälle des Error-Handlings), d.h. man schreibt Catch ex As IOException usw. Eine Liste der geworfenen Exceptions sollten der Dokumentation entnommen werden können.
    - Auch Err wird nicht mehr verwendet (ich weiß leider nicht mehr, ob es sich um eine Klasse oder eine Methode handelt, aber ich glaube eine Klasse), sondern man arbeitet direkt auf den Informationen, die die Exception ex bereitstellt

    Hat das vor der Umstellung auf Option Strict On denn anders funktioniert? Option Strict betrifft stets nur das von dir damit versehene Projekt/die von dir damit versehene Datei und hat keine Auswirkung auf die verwendeten Bibliotheken, usw. Es handelt sich nur um eine Anweisung für den Compiler.

    Ich vermute, dass es daran liegt, dass du durch dein Catch einen Fehler abfängst, den du nicht mehr mitbekommst. Du musst eine Meldung einbauen, dass der Fehler aufgetreten ist und außerdem Informationen bereitstellen, die es dir ermöglichen, den Fehler zu rekonstruieren sofern du nicht vorher weißt, dass er auftreten wird. Zum Beispiel bei fehlenden Rechten oder Dateizugriffen wird beabsichtigterweise ein Fehler abgefangen und entsprechend gehandhabt, d.h. man weiß, dass dieser Fehler möglicherweise auftritt und muss daher nicht erst debuggen, weshalb die Debugging-Informationen nicht nötig sind.

    Viele Grüße
    ~blaze~
    es lag nicht an meinem code....denn wenn sie einzeln aufgerufen werden war alles ok.
    das problem trat auf, wenn sie hintereinander ausgeführt werden.

    die lösung ist 1.tag zu schreiben, file schließen, neuen tag vom 2.tag zwischenspeichern, neu einlesen & wieder zuweisen & schreiben.

    das scheint wohl ein fehler von taglib zu sein...anders kann ich es mir nicht erklären.

    jedenfalls habe ich es dadurch geschafft die id3v1-klasse rausschreiben zu können.

    das problem hatte ich schon anfangs und habe es nicht lösen können....deshalb die klasse. durch rumprobieren habe ich es jetzt endlich geschafft....habe mir ne funktion gebastelt.

    und danke für deine ratschläge....werde sie beherzigen ;)
    hallo...:) heute gehts weiter mit strict on ;)

    ich hatte 2 subs, die List- & Comboboxen laden und speichern...hatte alles funktioniert.
    unter strict on sieht das etwas anders aus...ich habe lange rumprobiert, bis ich eine brauchbare lösung gefunden habe.

    jetzt möchte ich natürlich wissen, ob das auch besser oder kürzer geht...

    hier mal mein code von der load-routine...die save-routine ist etwas umfangreicher...ist aber vom prinzip her das gleiche:

    VB.NET-Quellcode

    1. Public Sub Box_LoadBox(ByVal Box As Control,
    2. ByVal frm As Form,
    3. ByVal LoadList As Boolean,
    4. ByVal LoadIndex As Boolean,
    5. ByVal LoadText As Boolean,
    6. Optional LoadMaxItems As Integer = -1)
    7. Dim Max, Count As Integer
    8. Dim Sektion, Read As String
    9. Dim isListbox As Boolean = False
    10. On Error Resume Next
    11. If TypeOf Box Is ListBox Then
    12. isListbox = True
    13. End If
    14. Sektion = frm.Name & Box.Name
    15. If LoadList = True Then
    16. If LoadMaxItems = -1 Then
    17. Max = -1
    18. Else
    19. Max = LoadMaxItems - 1
    20. End If
    21. Do
    22. Read = INI_Read(Sektion, Count.ToString)
    23. If Read.Length <> 0 Then
    24. If isListbox = True Then
    25. DirectCast(Box, ListBox).Items.Add(Read)
    26. Else
    27. DirectCast(Box, ComboBox).Items.Add(Read)
    28. End If
    29. Count += 1
    30. If Count = LoadMaxItems Then
    31. Exit Do
    32. End If
    33. Else
    34. Exit Do
    35. End If
    36. Loop
    37. End If
    38. If LoadIndex = True Then
    39. Read = INI_Read(Sektion, "Index")
    40. If Read.Length <> 0 Then
    41. If isListbox Then
    42. DirectCast(Box, ListBox).SelectedIndex = CInt(Read)
    43. Else
    44. DirectCast(Box, ComboBox).SelectedIndex = CInt(Read)
    45. End If
    46. Else
    47. If isListbox Then
    48. DirectCast(Box, ListBox).SelectedIndex = -1
    49. Else
    50. DirectCast(Box, ComboBox).SelectedIndex = -1
    51. End If
    52. End If
    53. End If
    54. If LoadText = True Then
    55. Box.Text = INI_Read(Sektion, "Text")
    56. End If
    57. Err.Clear()
    58. End Sub

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „woeh“ ()

    Hier mal Überarbeitung. Guck dir jede Zeile (auch die nicht mehr vorhandenen Leerzeilen) genauestens an.

    VB.NET-Quellcode

    1. ''' <summary> Kommentar fehlt - es ist unklar, was die Methode tun soll - besser noch wäre eine Benamung, die sich erklärt </summary>
    2. Public Sub LoadListControlFromIni(ByVal Box As ListControl, ByVal frm As Form, ByVal LoadList As Boolean, ByVal LoadIndex As Boolean, ByVal LoadText As Boolean, Optional LoadMaxItems As Integer = -1)
    3. ' On Error Resume Next - böse. Entweder vernünftige Fehlerbehandlung mit TryCatch (ich glaube aber, ist garnet möglich) oder **keine** Fehlerbehandlung (100mal besser als eine falsche Fehlerbehandlung).
    4. Dim isListbox = TypeOf Box Is ListBox
    5. Dim Sektion = frm.Name & Box.Name
    6. If LoadList Then ' siehe: https://www.vb-paradise.de/index.php/Thread/110889-Boolean-Vergleiche-und-bedingte-Verzweigungen/
    7. If LoadMaxItems < 0 Then LoadMaxItems = Integer.MaxValue
    8. For i = 0 To LoadMaxItems
    9. Dim Read = INI_Read(Sektion, i.ToString)
    10. If Read.Length = 0 Then Exit For
    11. If isListbox Then
    12. DirectCast(Box, ListBox).Items.Add(Read)
    13. Else
    14. DirectCast(Box, ComboBox).Items.Add(Read)
    15. End If
    16. Next
    17. End If
    18. If LoadIndex Then
    19. Dim Read = INI_Read(Sektion, "Index")
    20. Box.SelectedIndex = If(Read.Length <> 0, CInt(Read), -1)
    21. End If
    22. If LoadText Then Box.Text = INI_Read(Sektion, "Text")
    23. End Sub
    Es wird auch nicht ganz lauffähig sein, weil ich kanns ja nicht testen.
    GESCHAFFT !!!!!

    alle 500 fehler sind behoben und ich habe es auf strict on laufen !!!

    NOCHMAL VIELEN HERZLICHEN DANK AN EUCH !!!

    ich habe immer If Bla = True/False für die besswere lesbarkeit geschrieben.
    mir hat es geholfen....ok...es ist ne sinnlose rechnerei...das stimmt wohl...daran habe ich nie gedacht.

    deshalb und aus diesem grund werde ich alles True/False rauschreiben....soweit es möglich ist
    und mich davon verabschieden.

    ja....und da wären die kommentare und noch soviel zu tun....aber ich denke mit eurer hilfe werde ich das schaffen *Daumen Hoch*

    danke .)

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

    ich habe die routine jetzt mal nach meinem verständnis umgeschrieben.
    sind neue dinge dabei, die ich noch nicht kannte...
    ich hatte es auch kurz mir ListControl versucht....hatte da aber noch keine ahnung wie ich das nun machen soll und habe es wieder durch control ersetzt. habe vergessen daran zu denken, das ListControl ja ne SelectedIndex-Eigenschaft besitzt.
    was ich auch schön finde ist "If(Read.Length <> 0, CInt(Read), -1)"...wußte gar nicht, dass man so ne if-bedingung schreiben kann.
    ich habe dann noch die übergabe der Form rausgeschrieben. die wird jetzt mit ner funktion ermittelt.

    VB.NET-Quellcode

    1. Public Sub Box_LoadBox(ByVal Box As ListControl,
    2. ByVal LoadList As Boolean,
    3. ByVal LoadIndex As Boolean,
    4. ByVal LoadText As Boolean,
    5. Optional LoadMaxItems As Integer = -1)
    6. Dim p As Integer
    7. Dim Sektion, Read As String
    8. Dim frm As Form = ControlGetParentForm(Box)
    9. Dim isListbox As Boolean = TypeOf Box Is ListBox
    10. On Error Resume Next
    11. Sektion = frm.Name & Box.Name
    12. If LoadList Then
    13. LoadMaxItems -= 1
    14. If LoadMaxItems < 0 Then LoadMaxItems = Integer.MaxValue
    15. For p = 0 To LoadMaxItems
    16. Read = INI_Read(Sektion, p.ToString)
    17. If Read.Length = 0 Then Exit For
    18. If isListbox = True Then
    19. DirectCast(Box, ListBox).Items.Add(Read)
    20. Else
    21. DirectCast(Box, ComboBox).Items.Add(Read)
    22. End If
    23. Next p
    24. End If
    25. If LoadIndex Then
    26. Read = INI_Read(Sektion, "Index")
    27. Box.SelectedIndex = If(Read.Length <> 0, CInt(Read), -1)
    28. End If
    29. If LoadText Then
    30. Box.Text = INI_Read(Sektion, "Text")
    31. End If
    32. Err.Clear()
    33. End Sub
    34. Public Function ControlGetParentForm(ByVal crtl As Control) _
    35. As Form
    36. crtl = crtl.Parent
    37. Do While TypeOf crtl IsNot Form
    38. crtl = crtl.Parent
    39. Loop
    40. Return DirectCast(crtl, Form)
    41. End Function


    so....und jetzt muß ich die raubtiere füttern gehen.
    Arrr. Noch immer On Error. Wo erwartest Du genau welche Art von Fehler?
    Bzgl. der 2. Sub:

    VB.NET-Quellcode

    1. Public Function ControlGetParentForm(ctrl As Control) As Form
    2. Do
    3. ctrl = ctrl.Parent
    4. Loop Until TypeOf ctrl Is Form
    5. Return DirectCast(ctrl, Form)
    6. End Function
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Arrr. Noch immer On Error. Wo erwartest Du genau welche Art von Fehler?
    Und immer noch haufenweise Leerzeilen ohne Sinn.
    Und immer noch 3-zeilige Ifs, wo ein Einzeiler reichen täte.
    Und immer noch werden Booleans mit True verglichen. siehe: Boolean, Vergleiche und bedingte Verzweigungen
    Und das Schlüsselwort ByRef ist auch völlig üflüssig.
    Ich gebs ja zu, mein Code ist wg der langen Comments nicht gut zu lesen - aber wenn du die Comments befolgst, können sie ja auch weg.

    VB.NET-Quellcode

    1. Public Sub LoadListControlFromIni(Box As ListControl, frm As Form, _
    2. LoadList As Boolean, LoadIndex As Boolean, LoadText As Boolean, Optional LoadMaxItems As Integer = -1)
    3. Dim isListbox = TypeOf Box Is ListBox
    4. Dim Sektion = frm.Name & Box.Name
    5. If LoadList Then
    6. If LoadMaxItems < 0 Then LoadMaxItems = Integer.MaxValue
    7. For i = 0 To LoadMaxItems
    8. Dim Read = INI_Read(Sektion, i.ToString)
    9. If Read.Length = 0 Then Exit For
    10. If isListbox Then
    11. DirectCast(Box, ListBox).Items.Add(Read)
    12. Else
    13. DirectCast(Box, ComboBox).Items.Add(Read)
    14. End If
    15. Next
    16. End If
    17. If LoadIndex Then
    18. Dim Read = INI_Read(Sektion, "Index")
    19. Box.SelectedIndex = If(Read.Length <> 0, CInt(Read), -1)
    20. End If
    21. If LoadText Then Box.Text = INI_Read(Sektion, "Text")
    22. End Sub

    Beachte: Bei mir ists nicht die Hälfte Code-Zeilen, wo man durchsteigen muss.

    Übrigens: Fühl dich nicht zu sehr bemeckert.
    Ich finds sehr gut, dass du den Code nicht kopierst :thumbsup: , sondern deine eigene Version schreibst.
    Und logisch übersiehste dabei einiges - aber das ist besser als ein Copy/Paste, wo man garnet hinguckt.

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

    Es gibt keinen Unterschied. Wenn Dir ein 3-Zeiler lieber ist, dann nimm ihn. Ich bevorzuge Einzeiler, zumindest solange nicht noch 3 Geschichten hinterherkommen. Also sowas ist für mich auch ein Mehrzeiler wert:
    If ComputerIsDoingSomethingStupid Then StopTheComputer: GiveHimAWatschn: HauHimOnTheNonExistingFingers: StartAllOverAgain
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    woeh schrieb:

    ... ob ich ne bedingung in einer zeile oder in drei zeilen schreibe ?
    für die lesbarkeit finde ich drei zeilen besser...

    hat es einen tieferen sinn ?
    Jo, ich seh den Sinn inne besseren Lesbarkeit.
    Lesbarkeit wird immer belastet durch viele Zeilen, mit Vor- und Rücksprüngen.
    Und Einzeiler-Ifs sind mir ein willkommenes Mittel, beides ein bischen weniger zu haben.
    zu meiner frage welcher der unterschied zw. InStr und .IndexOf und dergleichen ist, ist mir aufgefallen, dass die kompilierte exe kleiner wird, wenn ich die .Net-schreibweise nutze.

    habe aber noch soviel zu tun...RegEx möchte ich mich auch noch aneignen...aber eines nach dem anderen...erstmal richtige schreibweise.

    woeh schrieb:

    wenn ich die .Net-schreibweise nutze.
    Klar, da wird einiges VisualBasic-Zeugs nicht benötigt.
    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!