Reputation: 1220
I know there's no straightforward way for multiple assignment of function in VB
, but there's my solution - is it good, how would you do it better?
What I need (how would I do it in python, just an example)
def foo(a) ' function with multiple output
return int(a), int(a)+1
FloorOfA, CeilOfA = foo(a) 'now the assignment of results
How I do it in VB:
Public Function foo(ByVal nA As Integer) As Integer() ' function with multiple output
Return {CInt(nA),CInt(nA)+1}
End Function
Dim Output As Integer() = foo(nA) 'now the assignment of results
Dim FloorOfA As Integer = Output(0)
Dim CeilOfA As Integer = Output(1)
Upvotes: 16
Views: 74718
Reputation: 35400
For future readers, VB.NET 2017 and above now supports value tuples as a language feature. You declare your function as follows:
Function ColorToHSV(clr As System.Drawing.Color) As (hue As Double, saturation As Double, value As Double)
Dim max As Integer = Math.Max(clr.R, Math.Max(clr.G, clr.B))
Dim min As Integer = Math.Min(clr.R, Math.Min(clr.G, clr.B))
Dim h = clr.GetHue()
Dim s = If((max = 0), 0, 1.0 - (1.0 * min / max))
Dim v = max / 255.0
Return (h, s, v)
End Function
And you call it like this:
Dim MyHSVColor = ColorToHSV(clr)
MsgBox(MyHSVColor.hue)
Note how VB.NET creates public property named hue
inferred from the return type of the called function. Intellisense too works properly for these members.
Note however that you need to target .NET Framework 4.7 for this to work. Alternately you can install System.ValueTuple
(available as NuGet package) in your project to take advantage of this feature.
Upvotes: 20
Reputation: 5139
Maybe you can use Tuple:
Public Function foo(ByVal nA As Integer) As Tuple(Of Integer,Integer) ' function with multiple output
Return Tuple.Create(CInt(nA),CInt(nA)+1)
End Function
Dim FloorOfA, CeilOfA As Integer
With foo(nA) 'now the assignment of results
FloorOfA =.item1
CeilOfA = .item2
End With
Edit: New Tuple replace by Tuple.Create (thanks to @mbomb007)
Upvotes: 3
Reputation: 216293
Your solution works and it is an elegant way to return multiple results, however you could also try with this
Public Sub foo2(ByVal nA As Integer, ByRef a1 As Integer, ByRef a2 As Integer)
a1 = Convert.ToInt32(nA)
a2 = Convert.ToInt32(nA) +1
End Sub
and call with
foo2(nA, CeilOfA, FloorOfA)
If you have many results to return it is logical to think to a class that could return all the values required (Expecially if these values are of different dataTypes)
Public Class CalcParams
Public p1 As Integer
Public p2 As String
Public p3 As DateTime
Public p4 As List(Of String)
End Class
Public Function foo2(ByVal nA As Integer) As CalcParams
Dim cp = new CalcParams()
cp.p1 = Convert.ToInt32(nA)
.......
Return cp
End Function
Upvotes: 9
Reputation: 67207
The methodology you are using is a good one, by the way, you can pass the required variable as a reference
to your subroutine
inorder to make your code
more cleaner.
Dim FloorOfA As Integer
Dim CeilOfA As Integer
Call foo(10.5, FloorOfA, CeilOfA)
Public Sub foo(ByVal xVal As Integer, ByRef x As Integer, ByRef y As Integer)
x = CInt(xVal)
y = CInt(xVal) + 1
End Sub
Upvotes: 3