Dispose und Nothing in einer Extension-Prozedur [gelöst]

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    Dispose und Nothing in einer Extension-Prozedur [gelöst]

    Ich steh grad auf'm Schlauch. Trotzdem geh ich davon aus, dass das Ganze hier schnell zu lösen ist.
    Ich hatte ne IDisposable-Extension in nem alten Projekt gefunden:

    VB.NET-Quellcode

    1. Public Module Ex
    2. <Runtime.CompilerServices.Extension>
    3. Public Sub DisposeAndNullify(DisposableObject As IDisposable)
    4. DisposableObject?.Dispose()
    5. DisposableObject = Nothing
    6. End Sub
    7. End Module

    Damals dachte ich, dass es toll wäre, wenn man z.B. nen StreamReader längere Zeit verwendet*, ihn am Ende des Programms nicht mehr braucht und dann eben für ihn DisposeAndNullify aufruft, damit die Variable, die den StreamReader beinhaltet nun den Wert Nothing hat. Zu doof, dass ich es nicht getestet habe.

    *daher scheidet ein Using-Block aus

    VB.NET-Quellcode

    1. Dim MyStreamReader As StreamReader = Nothing
    2. '...
    3. MyStreamReader = New StreamReader(PathToFile)
    4. '...
    5. MyStreamReader.DisposeAndNullify
    6. '...
    7. Dim CurEnc = MyStreamReader?.CurrentEncoding 'liefert hoffentlich Nothing für MyStreamReader und CurEnc

    Klappt natürlich nicht. Die Variable, die in der Extension verwendet wird, hat ja diesbezüglich keinen Einfluss auf MyStreamReader. Jetzt die Frage, bei der ich auf'm Schlauch stehe: Kann man das überhaupt in VB.Net umsetzen, ohne explizit zu schreiben:

    VB.NET-Quellcode

    1. MyStreamReader.Dispose
    2. MyStreamReader = Nothing
    Ich befürchte nicht.




    (Haupt-)Lösung in Post#8
    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.

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

    Wozu brauchst Du für den Streamreader diese Extension?
    docs.microsoft.com empfiehlt für deine Methode sogar ausdrücklich einen Try-Catch Block, naja. Jedenfalls bist Du für das Schliessen und Disposen selbst verantwortlich.
    Anderfalls schreibst Du Deinen Code so um, dass die Datei doch in einem Using Konstrukt abgearbeitet wird.
    @VaporiZed Das Using wird letztenendes in ein Try / Finally übersetzt.

    VB.NET-Quellcode

    1. MyStreamReader = Nothing
    2. Dim CurEnc
    3. Try
    4. MyStreamReader = New StreamReader(PathToFile)
    5. ' MyStreamReader verwenden
    6. CurEnc = MyStreamReader.CurrentEncoding
    7. Finally
    8. If MyStreamReader IsNot Nothing Then MyStreamReader.Dispose()
    9. End Try
    Geht das iwie?
    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!
    Anscheinend bin ich mal wieder nicht in der Lage, mein Anliegen deutlich genug rüberzubekommen :(

    @Dksksm: Ich brauche es nicht (nur) für nen StreamReader, sondern für alle disposable objects.

    VaporiZed schrieb:

    Damals dachte ich, dass es toll wäre, wenn man z.B. nen StreamReader längere Zeit verwendet* [...] *daher scheidet ein Using-Block aus
    Mir ist die Existenz von Using bekannt. Aber manchmal braucht man gewisse Objekte, die etwas länger gebraucht werden. In einem aktuellen Projekt z.B. eine CancellationTokenSource. Aber hier geht's ja um ne konzeptionelle Sache, nämlich:
    @RodFromGermany: Es geht mir ja auch darum, am Ende MyStreamReader oder eine entprechende Variable, die auf ein disposable object zeigt, auf Nothing zu setzen. Ich kann es ja problemlos wie geschrieben selber "per Hand" machen:

    VB.NET-Quellcode

    1. MyStreamReader.Dispose
    2. MyStreamReader = Nothing

    Aber es geht mir darum, sowas im Sinne von DRY auszulagern.
    @ErfinderDesRades: Ehm. Nö. As Disposable wird bei mir nicht erkannt. Auch nicht mit IDisposable. Welchen Verweis habe ich vergessen? VS macht mir keine Vorschläge, G**gle auch nicht. Aber vielleicht seh ich den Baum vor lauter Wäldern nicht.
    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.

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

    VaporiZed schrieb:

    wird bei mir nicht erkannt. Auch nicht mit IDisposable.
    Lass da mal ne Codeanalyse drüber laufen.
    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!

    VaporiZed schrieb:

    As Disposable wird bei mir nicht erkannt. Auch nicht mit IDisposable
    Jou, das war ein sehr missverständlicher Satz von mir, da ich das an der falschen Stelle in den Text geschrieben habe. IDisposable ist mir natürlich bekannt, verwendete ich ja schon im Eingangspost. Was ist sagen wollte: Mit Of T As IDisposable klappt es auch nicht. Dass Of T As Disposable bleibt jedoch ein Compilerfehler bei mir.
    Bzgl. der Codeanalyse mit alle Mikrosaft-Regeln kommt nur:

    Quellcode

    1. Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
    2. Warnung CA1709 Korrigieren Sie im Member 'Ex.DisposedAndNullified(Of T)(T)' die Schreibweise von "Disposable" im Parameternamen 'DisposableObject' in disposable.

    Irgendwie glaub ich nicht, dass es das ist, was Du mir sagen wolltest.

    ##########

    Etwas Frischluft hätte mir vor Threaderstellung gutgetan.

    VB.NET-Quellcode

    1. Public Module Ex
    2. <Runtime.CompilerServices.Extension>
    3. Public Function DisposedAndNullified(Of T As IDisposable)(DisposableObject As T) As T
    4. DisposableObject?.Dispose()
    5. DisposableObject = Nothing
    6. Return DisposableObject
    7. End Function
    8. End Module

    -->

    VB.NET-Quellcode

    1. Dim TestObject As New Form1
    2. TestObject = TestObject.DisposedAndNullified
    3. End Sub
    4. End Class

    Zwar wegen doppelter Verwendung von TestObject und Verwendung einer Function nicht ganz, was ich wollte, aber ein Einzeiler, der seinen Zweck erfüllt.
    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.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „VaporiZed“ ()

    Hab's zwar nicht getestet aber Dispose() dürfte funktionieren, = null wird aber nie klappen. Der Parameter in deiner Extension ist ja nichts Anderes als der Zeiger auf das IDisposable Objekt. Den kannst du natürlich auf 0 setzen, das ändert aber nichts am "Originalzeiger" der wurde ja nur kopiert. Was du bräuchtest wäre ein Zeiger auf einen Zeiger. K.A. obs sowas in VB gibt. Vielleicht mit ByRef, kann aber sein dass der Compiler das automatisch auflöst.

    Edit:
    Du kannst auch einfach Null returnen, das spart dir die eine Zeile mit der Zuweisung.
    Ja perfekt. Das ByRef hat's gebracht! Ich bin immer davon ausgegangen, dass ein ByRef bei Objekten überflüssig wär. Falsch gedacht. Damit ist die Extension als Sub doch möglich.

    VB.NET-Quellcode

    1. Public Module Ex
    2. <Runtime.CompilerServices.Extension>
    3. Public Sub DisposeAndNullify(Of T As IDisposable)(ByRef DisposableObject As T)
    4. DisposableObject?.Dispose()
    5. DisposableObject = Nothing
    6. End Sub
    7. End Module

    Das Of T As IDisposable, was vom EdR vorgeschlagen wurde, ist aber dennoch nötig, sonst gibt's Mecker mit dem Compiler, aber macht ja nix.
    problem solved. Merci.
    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.

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