eigenes Konstrukt äquivalent zur MID-Anweisung gesucht

  • VB.NET

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

    eigenes Konstrukt äquivalent zur MID-Anweisung gesucht

    Ich frag mich zwar schon seit einigen Monaten, wie man quasi eine eigene Anweisung schreibt, die den gleichen Aufbau wie die MID-Anweisung hat, seh aber den Baum vor lauter Arbeitswäldern nicht. Laut dotnetpearls wird die MID-Anweisung zwar zu ner StringType.MidStmtStr-Methode umgewandelt, von der es dann aber im MSDN heißt: "Bitte nicht selber benutzen!", aber vielleicht ist das auch schon wieder ne falsche Abzweigung des Lösungswegs.

    Kurz:

    VB.NET-Quellcode

    1. Dim TS As String = "Teststring"
    2. Mid(TS, 1, 3) = "bla"

    -> aus "Teststring" wird "blatstring"

    Wie baut man ein eigenes Konstrukt in der Form MySpecialCodeMonster(TS, 1, 3) = "bla"? Natürlich ohne MID zu verwenden? Es geht mir noch nicht mal um korrekte Funktionalität, sondern nur um den Class(?)-/Structure(?)-/Sub(?)-/Funcion(?)-/Property(?)/wasauchimmer-Aufbau. Bisher habe ich diese Kandidaten (außer natürlich "wasauchimmer" ;) ) verwendet, um den gleichen Syntax hinzubekommen. Aber natürlich ohne Erfolg, sonst würd ich kein neues Thema aufmachen.
    Ich hab zwar momentan noch keine Anwendung dafür, aber für mich als Unwissender scheint mir die MID-Anweisung erstmal ne Ausnahmekonstruktion zu sein. Es geht auch eher um Grundsatzverständnis.

    ~blaze~: Thema verschoben
    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 „~blaze~“ ()

    In .Net sind Strings immutable. D.h. es ist nicht vorgesehen, einen bestehenden String nachträglich zu verändert. Dagegen verstösst dieses MID()-Dingens schonmal, und zwar vmtl, indem es den Parameter byRef übernimmt, und austauscht durch einen anneren string.
    Sauberer fändich eine String-Extension, die 2 Strings verarbeitet, und das Ergebnis returnt, sowas:

    VB.NET-Quellcode

    1. dim s = "Teststring".ReplaceChars(1, 3, "bla")

    Hi
    ich würde dafür einen StringBuilder verwenden und jeweils Append(value, startIndex, count) verwenden. Man kann Strings zwar editieren (in C# z.B. mit unsafe, in VB.Net mit GCHandle und Marshal), sollte das aber tunlichst unterlassen, wie gesagt wurde.

    Im StringBuilder kann man dann auch wild umeinandereditieren.

    Der Vorgang mit GCHandle wäre, dass du als erstes über GCHandle.Alloc den String anpinnst und danach die Daten an die jeweilige Adresse schreibst.

    VB.NET-Quellcode

    1. Dim s As String = "diesIstEinTest"
    2. Dim gch = System.Runtime.InteropServices.GCHandle.Alloc(s, System.Runtime.InteropServices.GCHandleType.Pinned)
    3. Try
    4. Dim ptr As IntPtr = gch.AddrOfPinnedObject()
    5. System.Runtime.InteropServices.Marshal.Copy("ersatz".ToCharArray(), 0, p, 2)
    6. Finally
    7. gch.Free()
    8. End Try


    Oder so in der Art.
    Strings können in .Net interned oder nicht interned sein. Wenn sie interned sind, sind sie quasi in einer Art Tabelle verankert, die von der CLR verwaltet wird und alle - naja - interned Strings enthält. Die Tabelle sorgt afaik dafür, dass die interned Strings nur ein Einziges mal im Speicher liegen. Das hat den Vorteil, dass Äquivalenzvergleiche halt sehr günstig sind, da nur noch die Adressen verglichen werden müssen. Ändert man daher dann eine Instanz über diese Eingriffe, ändert man alle Instanzen. Außerdem kann es auch sein, dass diverse Metadaten falsch sind, sofern welche über den String angelegt werden. ich kann mir bspw. vorstellen, dass die CLR Hashcodes für die Strings bereithält, die dann verfallen würden. Wie es mit nicht-interned Strings aussieht, weiß ich nicht.

    Viele Grüße
    ~blaze~
    1. Insomnia schlägt bei mir zu.
    2. Ich hab bei der Threaderstellung wohl irgendwas übersehen, denn der Thread ist im falschen Unterforum. Es wird wohl da eröffnet, wo man sich grad befindet, wenn man auf [Neues Thema] klickt. Ich bitte um Korrektur.
    3. Ich hab es wohl trotz langem Intro nicht geschafft, mein Problem korrekt zu beschreiben.
    Wie gesagt, es geht mir nicht um die Funktionalität der Mid()-Anweisung (ich melde mich jetzt schnell, bevor noch jemand mit RegEx anfängt), sondern um deren Syntax: A(Objektinstanz, WertFürParameter1, WertFürParameter2) = NeuerWert. Ich finde diesen einmalig und kann ihn nicht reproduzieren. Für mich sieht dieser Syntax wie das Gegenteil zu einer Extension aus.


    man schreibt bei der Anwendung
    man codiert in ner DLL die Funktionalität mit
    Extension-Syntax
    Objektinstanz.Methode(Parameter)
    Methode(Objekt, Parameter)
    gesuchter Syntax
    Methode(Objekt, Parameter) = Wert
    ??? (gesuchter Codesyntax)

    Extension-Beispiel (ob es ein gutes Beispiel ist, sei mal dahingestellt):
    Im Ziel-Projekt:

    VB.NET-Quellcode

    1. Dim s As New Stream
    2. s.DisposeAndNullify()


    In der dahinterliegenden DLL (oder woauchimmer):

    VB.NET-Quellcode

    1. <Extension>
    2. Public Sub DisposeAndNullify(dispoObj as IDisposable)
    3. dispoObj.Dispose()
    4. dispoObj = Nothing
    5. End Sub


    gesuchter-Syntax-Beispiel (leider ist die Mid()-Anweisung das einzig mir bekannte Kostrukt mit diesem Syntax, sonst würde ich ein anderes Beispiel verwenden:
    Im Ziel-Projekt:

    VB.NET-Quellcode

    1. Mid(fooString, 5, 7) = "bar"


    In der dahinterliegenden DLL (oder woauchimmer; habe hier C-Syntax, da es in vb-Code m.E. etwas unübersichtlich wär):

    C-Quellcode

    1. ???
    2. public string string::Mid(int Parameter1, int Parameter2) = string NewValue //funktioniert natürlich nicht, eben weil ich ja hier den Syntax suche, v.a. in vb
    3. {
    4. }

    Ich hoffe, ich habe nun alle Klarheiten beseitigt.
    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 7 mal editiert, zuletzt von „VaporiZed“ ()

    Mid ist eine Ausnahme, die zur Kompatibilität zu VB6 übernommen wurde. Und das ist auch die einzige Ausnahme, die mir da bekannt ist.
    Funktionsaufrufen etwas zuzuweisen funktioniert in VB nicht (eben bis auf die Ausnahme), denn Funktionen geben was zurück.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    @VaporiZed Wie wäre es mit einer ordentlichen String.Format-Anweisung?
    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!
    Es geht nicht um die Funktionalität, sondern die Syntax, sagte er weiter oben.

    Mir fiele jetzt ein Ansatz über die Default-Property auf einem Struct ein. Dabei hätte man keine Funktion, sondern eine Eigenschaft, die ein Struct zurückliefert. Dieses Struct hat eine Default-Property, die die Argumente annimmt, die du übergeben willst (string, int, int) und sowohl Getter, als auch Setter. Der setter ermöglicht dann halt die Zuweisung in der Form, wie sie bei Mid wohl möglich ist. Wenn der erste Parameter by reference übergeben wird, kannst du ihn auch setzen.
    Eine andere Möglichkeit fällt mir nicht ein. Der Zuweisungsoperator kann in .Net nicht überschrieben werden.

    Viele Grüße
    ~blaze~
    @~blaze~: Herzlichsten Dank. Property-Parameter dürfen zwar nicht mit ByRef versehen werden, aber ich kann zumindest eine Klasse übergeben, die dann im Setter auch nach außen verändert werden kann. Vielleicht bekomm ich das noch mit String hin, aber das ist erstmal nicht so wichtig. Die Syntax (danke für die implizite Grammatikkorrektur) ist erreicht. Thread closed.
    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.
    @Niko Ortner: Wie im Eingangspost erwähnt: Ich habe (noch) keine Anwendung dafür, es ging wirklich nur um das Grundsatzverständnis, wie ein derartig merkwürdiges Konstrukt K in die .Net-Welt passt und es schafft, eine Objektinstanz O mithilfe der Parameter P (K(O, P) = Wert) zu verändern. Und zwar eben mit dieser speziellen Syntax, die der restlichen .Net-Welt wesensfremd zu sein scheint. Oder wie man es eben mit allen möglichen Tricks nachbauen könnte, was mit ~blaze~s Vorschlag recht gut ging.

    kurz: Keine Anwendung, nur Syntaxverständnis
    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.