views:

62

answers:

4

Hi

I have the following code sample, where the only difference between the 2 parts of the If statement is the less than/greater than operators.

Is there a better way to write this? Could almost do with being able to define an Operator variable.

        If myVar = true Then

            Do While (X < Y)
                'call Method A
                'the values of X and Y will change within this loop
            Loop

        Else

            Do While (X > Y)
                'call Method A
                'the values of X and Y will change within this loop
            Loop

        End If

thanks

A: 
Do While ((myVar And X < Y) Or (Not myVar And X > Y))
    ' call Method A
Loop
codeulike
+2  A: 

You can use the ternary conditional operator, If, as of VB 2008:

Do While (If(myVar, X < Y, X > Y)))
    'call Method A
Loop

However, this will check myVar on every iteration instead of just once, which is bad for performance.

Samir Talwar
Thanks - I don't think performance is an issue too much here as the values of X and Y are always less than 10! This compiles in VS 2008, against .NET 2.0, but not in VS 2005 against .NET 2.0 - do you know why?
Richard Bysouth
In VS2005 you have to use the Iif operator instead (and cast it to CInt). You can see a sample of that in my answer.
ho1
@Richard: I'd recommend @ho's answer over mine. It's a lot more efficient.
Samir Talwar
+2  A: 
Dim from As Integer = CInt(iif(myVar, x, y))
Dim until As Integer = CInt(iif(myVar, y, x))

While from < until
    'call Method A
End While

Or if 2008 or newer, as Samir says, use the ternary conditional operator to avoid the CInt casts.

ho1
This answer's pretty good—it avoids the potential performance problem and is still very readable.
Samir Talwar
Good answer, but unfortunately that won't work in this case as the values of X and Y will change within the While loop (sorry, forgot to mention that first time round!)
Richard Bysouth
@Richard You can set "from" and "until" in the loop as well
Joel Coehoorn
@Joel - yes I realise that, but that would mean the extra overhead of the iif statements within the loop
Richard Bysouth
+1  A: 

You can use a delegate:

Public Function LessThan(Of T As IComparable)(ByVal A As T, ByVal B As T) As Boolean
    Return A.CompareTo(B) < 0
End Function

Public Function GreaterThan(Of T AS IComparable)(ByVal A As T, ByVal B As T)  As Boolean
    Return A.CompareTo(B) > 0
End Function

Dim comparer As Func(Of Integer,Integer,Boolean) = AddressOf GreaterThan(Of Integer)
If myVar Then comparer = AddressOf LessThan(Of Integer)

Do While comparer(X,Y)
    ''#call Method A
    ''#the values of X and Y will change within this loop
Loop

Of course, that needs VS2008. For more fun:

Do While CBool(Y.CompareTo(Y) * -1) = myVar
    ''#...
End While
Joel Coehoorn
Interesting answer indeed! I hadn't seen the Func Delegate before, but looks like I'll have to wait until my app moves on from .NET 2.0.I'll bear this in mind for later though thanks
Richard Bysouth
@Richard - you can define the Func delegate for yourself in .Net 2.0
Joel Coehoorn