Todd Main
Todd Main

Reputation: 29155

Pass in an Operator

Is there any way to pass in an operator in VB.NET? I'm looking to reduce my lines of code and for two functions there is literally only an operator that is different.

For example, I have two functions, Darken and Lighten. I'd like to get to a single function with as little code as possible. The only difference are Greater Than and Less Than operators.

Function Darken(ByVal clr1 As Color, ByVal clr2 As Color) As Color
    Dim newR = If(clr2.R < clr1.R, clr2.R, clr1.R)
    Dim newG = If(clr2.G < clr1.G, clr2.G, clr1.G)
    Dim newB = If(clr2.B < clr1.B, clr2.B, clr1.B)
    Return Color.FromArgb(newR, newG, newB)
End Function
Function Lighten(ByVal clr1 As Color, ByVal clr2 As Color) As Color
    Dim newR = If(clr2.R > clr1.R, clr2.R, clr1.R)
    Dim newG = If(clr2.G > clr1.G, clr2.G, clr1.G)
    Dim newB = If(clr2.B > clr1.B, clr2.B, clr1.B)
    Return Color.FromArgb(newR, newG, newB)
End Function

What I'd like is something like (pseudo):

Function DarkenLighten(By Val Op As Operator, ByVal clr1 As Color, ByVal clr2 As Color) As Color
    Dim newR = If(clr2.R Op clr1.R, clr2.R, clr1.R)
    Dim newG = If(clr2.G Op clr1.G, clr2.G, clr1.G)
    Dim newB = If(clr2.B Op clr1.B, clr2.B, clr1.B)
    Return Color.FromArgb(newR, newG, newB)
End Function

Is this possible? I couldn't find any reference if it is possible.

Upvotes: 2

Views: 630

Answers (5)

Adam Speight
Adam Speight

Reputation: 732

I would use the inline If combined with a Function lambda

Function DarkenLighten(Darken as Boolean,clr1 As Color, clr2 As Color) As Color
 Dim Op = If(Darken, Function(clr1,clr2) Math.Max(clr1,clr2), Function(x,y) Math.Min(clr1,clr2))
 Return Color.FromArgb(Op(clr1.R,clr2.R),Op(clr1.G,clr2.G),Op(clr1.B,clr2.B))
End Function

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1502446

You could pass in a Func(Of Byte, Byte, Boolean) and use a lambda expression. It would still be somewhat more verbose in VB than in C#, but not too bad.

Or you could use the Func approach but have "pseudo-constants" (read-only fields) for the various delegates. Then you could just refer to GreaterThan or LessThan. I don't believe there's an easy and concise way of converting the operator itself to a delegate.

Upvotes: 4

Jeriko
Jeriko

Reputation: 6637

I don't know VB.net, so I'm not sure if this is feasible, but couldn't you use something like compare()? Compare returns -1, 0, and 1 for <, == and > respectively. You could therefore pass -1, 0 or 1 to the function, as compare_value, and in your function have

if compare(a,b) == compare_value 
  do something...

Upvotes: 2

dbasnett
dbasnett

Reputation: 11773

This isn't shorter, but it does combine them. It should also be faster because it doesn't use the if operator.

Function DarkenLighten(ByVal Op As String, ByVal clr1 As Color, ByVal clr2 As Color) As Color

    Dim newR As Integer
    Dim newG As Integer
    Dim newB As Integer

    If Op = ">" Then
        If clr2.R > clr1.R Then newR = clr2.R Else newR = clr1.R
        If clr2.G > clr1.G Then newG = clr2.G Else newG = clr1.G
        If clr2.B > clr1.B Then newB = clr2.B Else newR = clr1.B
    ElseIf Op = "<" Then
        If clr2.R < clr1.R Then newR = clr2.R Else newR = clr1.R
        If clr2.G < clr1.G Then newG = clr2.G Else newG = clr1.G
        If clr2.B < clr1.B Then newB = clr2.B Else newR = clr1.B
    Else
        Throw New Exception("Bad OP")
    End If

    Return Color.FromArgb(newR, newG, newB)

End Function

Upvotes: 1

spinon
spinon

Reputation: 10857

I have never seen this done. Nor is there an Operator type. At least I have never one. There is the operator keyword that is used for operator overloads but that's it.

Upvotes: 1

Related Questions