【问题标题】:VB function with multiple output - assignment of results具有多个输出的 VB 函数 - 结果分配
【发布时间】:2013-05-02 11:05:25
【问题描述】:

我知道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)

【问题讨论】:

  • nA 已经是Integer 时,没有理由使用CInt(nA)

标签: vb.net function variable-assignment mass-assignment


【解决方案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 包提供)以利用此功能。

【讨论】:

    【解决方案2】:

    您的解决方案有效,它是返回多个结果的一种优雅方式,但是您也可以尝试使用此方法

    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)    
    

    如果您有许多结果要返回,那么考虑一个可以返回所有所需值的类是合乎逻辑的(特别是如果这些值具有不同的数据类型)

    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
    

    【讨论】:

    • 对于这样的基本用途,真的需要实例化一个类吗?也许structure 就够了?
    • 这与返回数组没有太大区别。但是您是对的,只有两个参数和整数类型,您可以使用您的解决方案或通过 Ref 传递预期结果。当您需要处理复杂的数据时,事情会变得更加复杂。这只是一个例子(我承认,有点不太可能)
    • 是的,结构也可以很好地工作。您会有所收获,但这实际上取决于您调用此方法的次数。
    【解决方案3】:

    您使用的方法很好,顺便说一下,您可以将所需的变量作为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
    

    【讨论】:

      【解决方案4】:

      也许你可以使用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 替换新的 Tuple(感谢 @mbomb007)

      【讨论】:

      • 不知何故我不喜欢它......元组似乎很重,我只需要两个整数。 + 在with 中调用了多少次子程序 foo,一两次?
      • @Intelligent-Infrastructure:子程序只被调用一次。 'With' 替换了 'Output' 声明。元组允许避免被认为不是很好的做法的 byref 参数。您可以在算法中使用 .item1、.item2,从而避免 FloorOfA,CeilOfA 声明。
      • 我喜欢使用元组,但我不会在这里使用“With”。添加嵌套级别,仅用于访问多个返回结果。我会将结果分配给本地变量。 Dim Output = foo(nA) / Dim FloorOfA = Output.Item1。像有问题的代码,但使用元组而不是数组。
      • @ToolmakerSteve:“With”用于避免变量声明的必要性。尤其是在未使用选项推断并且需要完整声明 Dim Output as Tuple(Of Integer,Integer)= foo(nA) 的情况下。我承认这是个人品味的问题。
      • @IvanH 这就是Tuple.Create() 的用途,因此您不必使用如此冗长的声明。改用它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-02
      • 1970-01-01
      相关资源
      最近更新 更多