web-dev-qa-db-ja.com

VB複数の出力を持つ関数-結果の割り当て

VBで複数の関数を割り当てる簡単な方法はないことはわかっていますが、私の解決策があります。

私が必要とするもの(Pythonでどのようにそれを行うのですか、単なる例です)

def foo(a)    ' function with multiple output
    return int(a), int(a)+1

FloorOfA, CeilOfA = foo(a) 'now the assignment of results

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)

今後の読者のために、VB.NET 2017以降では、言語機能として値タプルがサポートされるようになりました。関数は次のように宣言します。

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

そして、あなたはそれをこのように呼びます:

Dim MyHSVColor = ColorToHSV(clr)
MsgBox(MyHSVColor.hue)

VB.NETが、呼び出された関数の戻り値の型から推定されるhueという名前のパブリックプロパティを作成する方法に注意してください。 Intellisenseもこれらのメンバーに対して適切に機能します。

ただし、これを機能させるには、.NET Framework 4.7をターゲットにする必要があることに注意してください。または、プロジェクトにSystem.ValueTuple(NuGetパッケージとして入手可能)をインストールして、この機能を利用できます。

7
dotNET

あなたの解決策は機能し、複数の結果を返すエレガントな方法ですが、これで試すこともできます

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

と電話する

foo2(nA, CeilOfA, FloorOfA)    

返す結果が多い場合は、必要なすべての値を返すことができるクラスを考えることが論理的です(特に、これらの値が異なるdataTypeである場合)

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
9
Steve

多分あなたは 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

編集:新しいタプルをTuple.Createに置き換え(@ mbomb007に感謝)

3
IvanH

使用している方法論は良い方法です。ところで、必要な変数をreferenceとしてsubroutineに渡して、codeをよりクリーンにすることができます。

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