Orcas introduces the IF operator - a new and improved IIF (Sophia Salim)

Orcas introduces the IF operator - a new and improved IIF (Sophia Salim)

  • Comments 18

One of my all time favorite features in C# and CPP has been the conditional operator (?:). The brevity and elegance introduced by this operator in the code is unparalleled. We had IIF in all the previous versions of VB.net, which was not an operator in the true sense (It was a call to a function). But now with Visual Studio 2008, we have taken an "i" from this function and promoted it to operator status. "IF" can now be used instead of "IIF". It provides full functionality of the IIF function with some very interesting additions of its own, including short-circuiting. It even comes in two flavors: the ternary flavor which mimics the functionality of the IIF function while adding some more to it, and the binary flavor which introduces a new sort of comparison/assignment. Before I start getting too vague, I will just delve into the details of how to use the greatness called the IF operator!

Note: I will touch only the ternary flavor in this blog, and will follow up with the binary if operator and other interesting examples for if in blogs to come.

The first and most basic use of IF is the universal "compare, choose and assign" which is the functionality of conditional operators, and the iif function. The following are the definitions of the three operands of IF(TestExpression, TruePart, FalsePart):

    1. TestExpression, is any expression that produces a boolean value or a value convertible to boolean. With option strict on the expression needs to produce a value that is either boolean or has a widening conversion to boolean.
    2. TruePart, is the return value of the IF operator if the test expression above evaluates to true. Note that the return type of the operator is decided based on the wider of the types of the truepart and the falsepart, e.g, if the truepart is an integer and the falsepart is a decimal, then decimal which is the wider of the two types will be the return value's type. For details on type conversions and for a list of wider and narrower types, please refer here
    3. FalsePart,  is the return value of the IF operator if the test expression evaluates to false. Here in lies the short-circuiting. If the test expression evaluates to true, the FalsePart is just ignored. The compiler will not touch it. It will not evaluate it. So as long as your test expression is true, you can do null references here, call functions on objects that do not actually exist, or anything that the parser will let you get away with. It will just not be evaluated. (Please do not think that I am recommending you to do any of the afore-mentioned evils, but as long as your test expression remains true you can get away with this). This can be very useful while calling a function on a variable which may not be instantiated, You can simply do:
    4. Dim return = If(var Is Nothing, foo1(), var.foo())

Now lets look at some code that shows the ternary flavor of the IF operator

Module Module1
    Public Class Number
        Private _RealPart As Double
        Public Property RealPart() As Double
            Get
                Return _RealPart
            End Get
            Set(ByVal value As Double)
                _RealPart = value
            End Set
        End Property


        Private _ComplexPart As Double
        Public Property ComplexPart() As Double
            Get
                Return _ComplexPart
            End Get
            Set(ByVal value As Double)
                _ComplexPart = value
            End Set
        End Property


        Public Sub New(ByVal pRealPart As Double, Optional ByVal pComplexPart As Double = 0.0)
            _RealPart = pRealPart
            _ComplexPart = pComplexPart
        End Sub

        Public Overrides Function ToString() As String
            Return If(_ComplexPart = 0.0, _RealPart.ToString(), _
                      _RealPart.ToString & " + " & _ComplexPart.ToString() & "i")
        End Function
    End Class

    Sub Main()
        Dim i As New Number(1)
        'The If operator looks checks the number to see if it is real or complex, and prints accordingly
        Dim NumberPrinter = Function(arg As Number) arg.RealPart.ToString & " + " & arg.ComplexPart.ToString() & "i"
        Console.WriteLine("i is a real number:")
        Console.WriteLine(If(i.ComplexPart = 0.0, i.RealPart.ToString(), NumberPrinter(i)))

        'Or the If operator can be moved inside the lambda to add to the elegance
        Dim j As New Number(1, 2)
        Dim NumberPrinter2 = Function(arg As Number) If(arg.ComplexPart = 0.0, arg.RealPart.ToString(), _
                                                        arg.RealPart.ToString & " + " & arg.ComplexPart.ToString() & "i")
        Console.WriteLine("j is a complex number:")
        Console.WriteLine(NumberPrinter2(j))

        'You can also use the short-circuiting feature of the if operator
        Dim k As Number
        Console.WriteLine("k does not have any value, so we print j again:")
        Console.WriteLine(If(k Is Nothing, j.ToString, k.ToString))
        k = New Number(3, 4)
        Console.WriteLine("And now for k with a value:")
        Console.WriteLine(If(k Is Nothing, j.ToString, k.ToString))

    End Sub

End Module

Notice how short-circuiting is used in the above code when k does not have a value (the first call). The call to a method from a null object is never evaluated.

For those addicted IIF users wondering if they can still use the legacy IIF function in Orcas, the answer is yes. We still support IIF, but with all the amazing things that you can do with the IF operator, why would you want to keep on typing those extra "i"s? And while you explore the many, many things that you can do with IF, I will be writing and posting more IF code and then some more! Until then,

Dim blog_next = If(bIFoundMoreInterestingScenarios, blogDelvingIntoIF, blogUnknown)

If you know what I mean :)

Leave a Comment
  • Please add 6 and 6 and type the answer here:
  • Post
  • It's just another C# rip-off.

    If you like ?: so much, then why not just use C#?

    There's nothing "visually basic" about ?:.

    With few exceptions, VB just takes C# features. It's essentially two different syntaxes to accomplish the same task. Sure, C# took from C++, Java etc.; however, none of those other languages are particularly attractive for managed .Net development.

    Really, what's the point? Just let VB evolve separate from C#. Give it a real reason to co-exist.

  • Wow, INTRODUCING the If-operator. Must be for a really powerful programming-language.

    I-IF? Every time I see VB I just get so reminded what a mess it is.

    And that other VB-command is just embarrassing, what is? Something like IFELSEWHERENOTIS... Whatever it was, just stupid.

  • While it seems that the old IIF statement is now fixed by providing short-circuting, the code no longer looks like VB.NET.

    The time tested, easy to read, comment and very easy to place a breakpoint on, just seems a better way to go. (see below code)  Placing a breakpoint on code that is all on one line is not as simple when debugging code like the below code.  Simple does not have a negative connotation, rather the opposite.  Simple is just better in the long run.  Anyone can write compact cryptic code.  However, great developers write code that can be maintained over time, even by new developers that get hired a year or two later.

    IF condition  Then

     do this

    ELSE

     do this

    END IF

    My benchmark is and will always be, is the code maintainable over time.

    "Great developers write maintainable code over the long haul."  Karl Shifflett

    Cheers,

    Karl

  • Karl:

    Try using your construction as a method arguement.

  • @Jonathan

    How bout, "Don't." Karl's point was to write easier to debug, step through, and maintain code.

    Piling construct into construct into construct doesn't fit that goal.

    But it does help create readable, maintainable code.

  • @Pete

    Jeez, this is a VB oriented blog. You might be better off hanging out in a C# blog somewhere.

    Most languages borrowed at least some elements from another language. That's not a bad thing.

  • I think the inline if operator (or ?: to me since my first love is C#) can be more readable when it is not abused. ie:

    Font.Color = If(num>=0, Black, Red)

    Even with no context, the meaning of this terse line of code is clear -- when num is negative the font should be red.  The structure of the expression makes it clear that this is just one property that relies on the value of another.  If you look at the alternative:

    if num > 0 then

      Font.Color = Black

    else

      Font.Color = Red

    EndIf

    has a number of things to go wrong.  I need to look at the two statements that are the "branches" of the if, and I need to make sure that if I change one, I change the other as well.  In effect, it doesn't express the INTENT of the code as well as the first form, in my oipinion.

    Functional if is syntactic sugar there is no doubt about it.  For loops are also syntactic sugar.  In my opinion readable code is code that uses the language idiom most similar to the intent of the code.

  • @John Melville

    I approve your comment :-)

    @Pete, follow Darin's advice and stay away from VB Blogs if you don't like it or use it.  You're just adding noise to constructive comments from the VB community.  Have you heard us criticizing C# for it's lack of XML Literals like VB 9 has?  No, because we use VB and make good use of it with it pros and cons.

    Now back to your regular programming...

  • I come from C# world and started developing in VB.NET during the last year.

    I really appreciate this new feature, thx team

  • New here, so don't bite.

    I agree with John Melville that the new IF is better manageble when debugging, but let's not forget that Basic is in essence a language a lot of people use for their first experiences with programming. In my humble opinion, the new IF is a lot less readable then the first. I like the usual IF, and with the auto-indent feature, even nested IF-blocks are manageble. And for fast decisions, the usual IF also has a single line feature: If num>0 Then font.color=black Else font.color=red

  • to the vb haters, If you hate, vb.net so much stay off the vbteam blog. Stick to your c# and shut up. It's not language it's syntax difference, if you want to do something useful tell me the differences between the CLR that is generated in a managed environment. We like what we like you like what you like, no problem, just don't put down something you don't use. Why not use both? I think every vb.net programmer can code in C# because most involved examples and sample code is in C# it doesn't take long to pickup the syntax especially if you have any kind of JAVA background. Don't put something down if you don't use it. And truly vb.net is just shorter than C# minus the braces that compiles to the same code.

  • Anon.  While your statement is understood it is hardly logical and tends to be on the side of a teenager not understanding the growth of languages.  For example you state, "VB just takes C# features".   That is a rather absurd understanding of C#.  Anders came from the Delphi world and brought his compiler understanding to the Dot Net world.  Then he chose to intermix VB with C++ as well as some Delphi (like a central object alas TObject and the System Object).  He also wanted to eliminate garbage collection and have a central repository of classes like Java.  Now, granted, C# is a fantastic language.  But VB 9 is not VB 6.  Generics, partial classes, partial methods, full OOP, reflection are not just powerful parts of C# but they are also part of VB9.

    So please feel free to leave the High School arena and appreciate that you are now amoung the men of the development arena. Welcome to Dot Net.

  • C# is a knock off of smalltalk, java, pascal (Delphi) and C++.

    VB.Net is simply a knock off of C#...

  • 私がずっと気に入っている C# と CPP の機能の 1 つは、条件演算子です。この演算子を使うと、簡潔で正確なコードを記述できます。以前のバージョンの VB.net には IIF がありましたが、これは厳密には演算子ではなく、関数呼び出しでした。

  • Thank you very much!

    M.Ahrens

Page 1 of 2 (18 items) 12