In if abfrage wert gleich zuweisen. Geht das?

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

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von Niko Ortner.

    In if abfrage wert gleich zuweisen. Geht das?

    Kennt jemand eine Möglichkeit in if Abfrage den Wert einer Variable gleich zu zuweisen? Ungefähr so:

    private function xy() as bool
    return true
    end funktion


    ...
    dim x as bool = false
    if x=xy() then ...

    jetzt müsste im x ein true stehen....

    Kennt jemand so eine abgekürzte Möglichkeit?
    Danke im Voraus
    dein Code ist etwas verwirrend... Du weist X=false zu und prüfst dann ob x=xy ist wobie xy ja true ist.... du müsstet doch eher der function einen Übergabewert geben und dann die function prüfen

    VB.NET-Quellcode

    1. ​private function xy(byval x as bool) as bool
    2. x=true
    3. return x
    4. end funktion
    5. '
    6. dim x as bool = false
    7. if xy(x) then ...


    oder sehe ich das falsch als Anfänger?
    "Hier könnte Ihre Werbung stehen..."
    Da es in C# funktioniert:


    Würde ich behaupten, dass es in VB auch funktioniert, jedoch scheint der SnippetConverter da das Handtuch zu werfen:

    VB.NET-Quellcode

    1. Dim x As Boolean
    2. If InlineAssignHelper(x, xy()) Then
    3. Console.WriteLine(x)
    4. End If

    InlineAssignHelper sieht für mich nicht nach etwas aus, das man normalerweise aufrufen würde....
    Ahoi,

    deine Logik stimmt, glaube ich, nicht ganz.
    Du willst doch x den Rückgabewert von xy() zuweisen, wenn x != xy().
    Hier gibts was dazu.

    Das sollte also so aussehen:

    VB.NET-Quellcode

    1. Sub Main()
    2. Dim x As Boolean = False
    3. x = If(x = xy(), x, xy())
    4. WriteLine(x)
    5. Console.ReadLine()
    6. End Sub
    7. Private Function xy() As Boolean
    8. Return True
    9. End Function
    Grüße Manu

    Was Gott dem Menschen erspart hat, kann der Computer.
    Billy ©, (*1932), Schweizer Aphoristiker
    Quelle: www.Aphorismen.de
    @Manü
    Es gibt 2 Fälle:
    1.: x == xy()
    2.: x != xy()
    Angenommen xy() ist 5:
    Im ersten Fall hat x schon den Wert 5.
    Im zweiten Fall wird x der Wert 5 zugewiesen.
    Das Ergebnis ist immer das gleiche: x hat nachher den Wert 5.
    Deshalb ist es unnötig, vorher auf Gleichheit zu prüfen.

    Aber ich glaube, das war nicht gemeint.
    Wie @EaranMaleasi gezeigt hat: In C# (bzw. generell C-artigen Sprachen) gibt es das, dass eine Zuweisung gleichzeitig ein Ausdruck ist.
    In VB gibt es das nicht ohne weiteres. Der =-Operator ist Kontext-abhängig:
    In einem Ausdruck vergleicht er und ergibt einen Boolean.
    In einem blanken Statement weist er was zu.
    Die InlineAssignHelper-Funktion müsste so aussehen:

    VB.NET-Quellcode

    1. Shared Function InlineAssignHelper(Of T)(ByRef Target As T, ByVal Value As T) As T
    2. Target = Value
    3. Return Value
    4. End Function

    Dekompiliert man das mal, sieht man, dass es ein ganzes Stück aufwändiger ist, als der =-Operator in C#:

    VB.NET-Quellcode

    1. Private Shared Sub Foo(A As Boolean, B As Boolean)
    2. If InlineAssignHelper(A, B) Then
    3. Console.WriteLine("Ja")
    4. Else
    5. Console.WriteLine("Nein")
    6. End If
    7. End Sub
    8. Private Shared Function InlineAssignHelper(Of T)(ByRef Target As T, ByVal Value As T) As T
    9. Target = Value
    10. Return Value
    11. End Function

    CIL-Quellcode

    1. .method private static void Foo(bool A, bool B) cil managed
    2. {
    3. //InlineAssignHelper mit Adresse von A und Wert von B aufrufen
    4. IL_0000: ldarga.s A
    5. IL_0002: ldarg.1
    6. IL_0003: call !!0 InlineAssignHelper<bool>(!!0&, !!0)
    7. // B wird von InlineAssignHelper zurückgegeben
    8. // Der Rest vom If-Block
    9. IL_0008: brfalse.s IL_0016
    10. IL_000a: ldstr "Ja"
    11. IL_000f: call void Console::WriteLine(string)
    12. IL_0014: br.s IL_0020
    13. IL_0016: ldstr "Nein"
    14. IL_001b: call void Console::WriteLine(string)
    15. IL_0020: ret
    16. }
    17. .method private static !!T InlineAssignHelper<T>(!!T& Target, !!T Value) cil managed
    18. {
    19. // Value dort hin kopieren, wo der Pointer hin zeigt
    20. IL_0000: ldarg.0
    21. IL_0001: ldarg.1
    22. IL_0002: stobj !!T
    23. // Value zurückgeben
    24. IL_0007: ldarg.1
    25. IL_0008: ret
    26. }

    Dagegen C#:

    C#-Quellcode

    1. private static void Foo(bool A, bool B)
    2. {
    3. if (A = B)
    4. {
    5. Console.WriteLine("Ja");
    6. }
    7. else
    8. {
    9. Console.WriteLine("Nein");
    10. }
    11. }

    CIL-Quellcode

    1. .method private hidebysig static void Foo(bool A, bool B) cil managed
    2. {
    3. // B direkt nach A kopieren
    4. IL_0000: ldarg.1
    5. IL_0001: dup
    6. IL_0002: starg.s A
    7. // B muss nicht erst durch eine Funktion geschliffen werden
    8. // Der Rest vom If-Block
    9. IL_0004: brfalse.s IL_0011
    10. IL_0006: ldstr "Ja"
    11. IL_000b: call void [mscorlib]System.Console::WriteLine(string)
    12. IL_0010: ret
    13. IL_0011: ldstr "Nein"
    14. IL_0016: call void [mscorlib]System.Console::WriteLine(string)
    15. IL_001b: ret
    16. }

    Inwiefern der JIT-Compiler das optimieren kann ist fraglich. Nicht dass es ein Performance-Problem wäre, aber schön ist es halt nicht.

    Um also die Frage von @EugenIS zu beantworten: Nein, ohne so eine Hilfsfunktion geht es nicht.
    Aber normalerweise ist es auch nicht nötig. Es gibt üblicherweise schönere Lösungen. Denn beachte: Bugs, bei denen der Programmierer if (a == b) meinte, aber versehentlich if (a = b) hinschreibt, passieren relativ häufig.
    Wenn Du uns ein konkretes Beispiel gibst, wo Du das verwenden möchtest, können wir Dir vielleicht zeigen, wie es besser zu lösen geht.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

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