Variable als Parameter übergeben und »für später« merken - geht das? [gelöst]

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

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

    Variable als Parameter übergeben und »für später« merken - geht das? [gelöst]

    Hallo zusammen,

    ich seh den Baum vor lauter Wäldern nicht. Vielleicht ist's zu spät, vielleicht will ich was, was in VB.NET gar nicht geht. Ich will eine an eine Funktion der Klasse X übergebende Variable erst später initialisieren, ohne sie nochmals an X übergeben zu müssen. Ein Beispiel:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Buzz As Bazz
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. Dim Foo As New Foo
    5. Foo.Remember(Buzz)
    6. Foo.ActivateTargetObject()
    7. End Sub
    8. End Class
    9. Public Class Foo
    10. Public Sub Remember(Bar As Bazz)
    11. '???
    12. End Sub
    13. Public Sub ActivateTargetObject()
    14. ??? = New Bazz
    15. End Sub
    16. End Class
    17. Public Class Bazz
    18. End Class

    Ich übergebe in Zeile#7 die Variable Buzz an Foo. Foo soll sich nun diesen Form1.Member merken (die Variable, nicht den Wert der Variable!) und später in ActivateTargetObject instanziieren. Folgendes ginge natürlich:

    VB.NET-Quellcode

    1. Foo.ActivateTargetObject(Buzz)
    2. '…
    3. Public Sub ActivateTargetObject(ByRef Bar As Bazz)
    4. Bar = New Bazz
    5. End Sub

    Aber geht das auch ohne Parameter? Oder geht das nur in C# mit Pointern?




    Lösung in Post#3/#5
    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“ ()

    Hallo @VaporiZed

    Die Variable Buzz ist in #3 noch nicht instanziert, und somit besteht auch noch keine Referenz (Zeiger) auf dem Stack, der auf dem Speicherbereich im Heap (da es eine Klasse ist) zeigt. Die Variable Buzz ist im moment unbestimmt, und zeigt auf Nothing.

    Vb.Net kann programmiertechnisch die Variable Buzz sich nicht "merken". Es kann nur ein Speicherbereich mittels Referenz (Zeiger) als Parameter übergeben werden, wobei der Referenzwert (und nur der Referenzwert, nicht der Speicher) im Normalfall kopiert wird.

    Wenn Buzz zu einem späteren Zeitpunkt instanziert werden soll, so muss das an Ort und Stelle erfolgen. Anderseits ist es aber möglich eine schon vorhandene Bazz-Instanzierung an Buzz zu übergeben.

    Freundliche Grüsse

    exc-jdbi

    VaporiZed schrieb:

    Oder geht das nur in C# mit Pointern?
    Äh, auch mit Pointern wäre das jetzt nicht so einfach umzusetzen, aber mit Lambda. Lambda oder anonyme Methoden sind black Magic können sich Referenzen merken (nicht wirklich glaube ich, aber haben irgendwie immer und überall zugriff auf alles) und daher nachträglich Felder setzen. So z.B. :

    C#-Quellcode

    1. namespace ConsoleApp1 {
    2. class Program {
    3. private static Bazz buzz;
    4. static void Main(string[] args) {
    5. Foo foo = new Foo();
    6. foo.Remember((newBuzz) => buzz = newBuzz);
    7. foo.ActivateObject();
    8. }
    9. }
    10. public class Foo {
    11. private Action<Bazz> barCreationLambda;
    12. public void Remember(Action<Bazz> barCreationLambda) {
    13. this.barCreationLambda = barCreationLambda;
    14. }
    15. public void ActivateObject() {
    16. barCreationLambda(new Bazz());
    17. }
    18. }
    19. public class Bazz {
    20. }
    21. }

    Das lässt sich nach VB.Net übersetzen oder?

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

    Ja funktioniert. Die Parameterübergabe muss mit ByRef kennzeichnet sein.

    VB.NET-Quellcode

    1. Public Sub Remember(ByRef barCreationLambda As Action(Of Bazz))
    2. Me.barCreationLambda = barCreationLambda
    3. End Sub


    EDIT: Komisch. Zwischendurch funkst es wiederum nicht, hab es gerade nochmals ausprobiert.
    Da jibbets eine neue dolle c#7-Feature, das kann das glaub:
    codeproject.com/Tips/5254144/Csharp-7-ref-returns-and-locals
    (Also mir fällt gelegentlich nützlicheres ein, was ich mir wünschen würde)



    Aber vb:
    Wurde schon gesagt: Man kann sowas mit Delegaten hinkriegen:

    VB.NET-Quellcode

    1. Imports System.Windows.Forms
    2. Public Class Form1
    3. Private Buzz As Bazz
    4. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    5. Dim Foo As New Foo With {.GetBazz = Function() Buzz, .SetBazz = Sub(b) Buzz = b}
    6. Foo.ActivateTargetObject()
    7. Foo.Remember()
    8. End Sub
    9. End Class
    10. Public Class Foo
    11. Public GetBazz As Func(Of Bazz)
    12. Public SetBazz As Action(Of Bazz)
    13. Public Sub Remember()
    14. Dim bz = GetBazz()
    15. MessageBox.Show(bz.GetType.Name)
    16. End Sub
    17. Public Sub ActivateTargetObject()
    18. SetBazz(New Bazz)
    19. End Sub
    20. End Class
    21. Public Class Bazz
    22. End Class

    (foo.Get-/Set-Bazz können auch privat readonly sein, und mit parametrisiertem Konstruktor injiziert)
    Ich hab iwann mal hier ein Riesen-Tut zu "Event-based Components" verzapft.
    Das ist eiglich ein sehr schönes Konzept zum Aufbau entkoppelter Architekturen - besser als Databinding.
    Hat sich leider nicht durchgesetzt - aber gelegentlich nehme ich Anleihe davon.
    (Wenn man sich das recht überlegt hat Wpf eiglich alles falsch gemacht - auf EBC aufgebaut hätte es viel smarter sein können.)

    Ach guck - hier habich nochwas dazu: Basic Benchmarks
    Da gibts die Klasse MemberAccess, die son Getter/Setter-Pärchen kapselt (und noch paar annere schlimme Dinge tut)

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

    Was du suchst ist ein Zeiger auf einen Zeiger. Buzz ist ja ein Zeiger, wenn du den ByRef übergibst hast du einen buzz** und kannst eine Instanz zuweisen (oder null). Ich glaube das Thema hatten wir schonmal im Bezug auf Dispose und direkt Null setzen.
    Buzz** kannst du nur nicht so einfach in einer Variablen ablegen. Es kann aber sein, dass es da schon eine Framework Klasse für gibt.
    Ja, perfekt, die guten Lambdas. Immer wieder was neues zu entdecken mit den Kandidaten. Genau das, was ich gerade gebraucht habe. Vielen Dank.
    @Gonger96: Das war hier, das ist aber im hiesigen Fall noch ne Stufe weiter.
    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.