将数组变量和其他变量传入和传出VB.Net子例程方法

时间:2018-08-05 16:08:52

标签: arrays vb.net methods parameter-passing subroutine

我正在转录代码,该代码处理从VB 6到VB.Net形式的复数数组。语言语法已经变得更加严格,并且我已经非常仔细地研究了ByVal和ByRef关键字的使用,以便我不能更改或更改通过方法子例程传递的变量。但是,似乎VB 6允许我将空变量传递到子例程中,并在调用行中接收更改的(内部计算的)变量。 VB.Net似乎不允许按规则将空变量传递到方法子例程中?在下面我分享的代码片段中,我只能通过将初始值随意设置为实际上在方法子例程中实际定义的参数来避免调用null异常。有没有办法避免这种繁琐的开销?

    Module Module1
    Sub Main()
        Dim Sx As Double() = {-0.0053, 0.8882, 0.8882, -0.0053}
        Dim Sy As Double() = {-0.0102, -0.4594, -0.4594, -0.0102}
        Dim Tx As Double() = {1.0, 1.0, 1.0, 1.0} 'To be calculated by method Stot and passed back to Main!
        Dim Ty As Double() = {1.0, 1.0, 1.0, 1.0} 'To be calculated by method Stot and passed back to Main!
        Stot(Sx, Sy, Tx, Ty) '[STh]--->[TTh]
        Console.WriteLine(Tx(0))
        Console.WriteLine(Ty(0))
        Console.WriteLine(Tx(1))
        Console.WriteLine(Ty(1))
        Console.WriteLine(Tx(2))
        Console.WriteLine(Ty(2))
        Console.WriteLine(Tx(3))
        Console.WriteLine(Ty(3))
        Stop
    End Sub
    Public Sub Stot(ByVal Sx As Double(), ByVal Sy As Double(), ByRef Tx As Double(), ByRef Ty As Double())
        Dim AA As Double
        Dim BB As Double
        Dim C As Double
        Dim D As Double
        Call Cmult(Sx(0), Sy(0), Sx(3), Sy(3), AA, BB)
        Call Cdiv(AA, BB, Sx(1), Sy(1), C, D) '(S11*S22)/S21
        Tx(0) = Sx(2) - C 'S12-((S11*S22)/S21)
        Ty(0) = Sy(2) - D
        Call Cdiv(Sx(0), Sy(0), Sx(1), Sy(1), Tx(2), Ty(2)) 'T12=S11/S21
        Call Cdiv(Sx(3), Sy(3), Sx(1), Sy(1), Tx(1), Ty(1)) 'T21=S22/S21
        Tx(1) = -1 * Tx(1) 'T21=-1*(S22/S21)
        Ty(1) = -1 * Ty(1)
        Call Cdiv(1, 0, Sx(1), Sy(1), Tx(3), Ty(3)) 'T22=1/S21
    End Sub
    Public Sub Cdiv(ByVal X1 As Double, ByVal Y1 As Double, ByVal X2 As Double, ByVal Y2 As Double, ByRef X3 As Double, ByRef Y3 As Double)
        Dim Denom As Double
        Denom = X2 * X2 + Y2 * Y2 'Multiplication by conjugate (X2+iY2)(X2-iY2)
        X3 = (X1 * X2 + Y1 * Y2) / Denom
        Y3 = (Y1 * X2 - X1 * Y2) / Denom
    End Sub
    Public Sub Cmult(ByVal X1 As Double, ByVal Y1 As Double, ByVal X2 As Double, ByVal Y2 As Double, ByRef X3 As Double, ByRef Y3 As Double)
        X3 = X1 * X2 - Y1 * Y2
        Y3 = X1 * Y2 + Y1 * X2
    End Sub
End Module

子例程StoT将S参数的矩阵转换为T参数的矩阵:这是常见的微波工程任务。它所做的并不重要,仅作为示例:如何在VB.Net中编码这种形式的数据共享是重要的一点。此控制台应用程序将数组参数定义为Double():双精度数字数组-用于复数的X和Y分量的单独数组(在Main方法中)。我知道数组自动符合VB.Net中的引用类型,因此不需要在调用的子例程StoT中将传递的参数定义为ByVal或ByRef。再次重复:我只能通过在“主要定义”中为输出参数Tx()和Ty()预先定义任意值,才能在不调用StoT中引发空异常的情况下使此调用起作用。 为了完成所需的算术任务,方法StoT需要执行复杂的除法和复杂的乘法任务,这些任务编码在方法子例程CDiv()和CMult()中。再次遵循只能使用ByRef关键字将数字作为输出数字提供的规则,它们接受并提供输出双精度数字。但是,即使这些调用生成不存在的应答复数,也不会调用null异常。所以我的问题是为什么。似乎不一致。...

1 个答案:

答案 0 :(得分:0)

我早就忘记了它在VB6中是否以不同的方式工作,但是在.NET中,当您传递Array ByRef时,可以在调用的方法中将参数分配给完全不同的数组。因此,如果传入Nothing,则可以分配一个新的Array并将该新的Array分配给ByRef参数。像这样:

Module Module1
    Sub Main()
        Dim Sx As Double() = {-0.0053, 0.8882, 0.8882, -0.0053}
        Dim Sy As Double() = {-0.0102, -0.4594, -0.4594, -0.0102}
        Dim Tx As Double() = Nothing '{1.0, 1.0, 1.0, 1.0} 'To be calculated by method Stot and passed back to Main!
        Dim Ty As Double() = Nothing '{1.0, 1.0, 1.0, 1.0} 'To be calculated by method Stot and passed back to Main!
        Stot(Sx, Sy, Tx, Ty) '[STh]--->[TTh]
        Console.WriteLine(Tx(0))
        Console.WriteLine(Ty(0))
        Console.WriteLine(Tx(1))
        Console.WriteLine(Ty(1))
        Console.WriteLine(Tx(2))
        Console.WriteLine(Ty(2))
        Console.WriteLine(Tx(3))
        Console.WriteLine(Ty(3))
        Stop
    End Sub
    Public Sub Stot(ByVal Sx As Double(), ByVal Sy As Double(), ByRef Tx As Double(), ByRef Ty As Double())
        Dim AA As Double
        Dim BB As Double
        Dim C As Double
        Dim D As Double

        If IsNothing(Tx) Then
            Tx = New Double() {1.0, 1.0, 1.0, 1.0}
        End If
        If IsNothing(Ty) Then
            Ty = New Double() {1.0, 1.0, 1.0, 1.0}
        End If

        Call Cmult(Sx(0), Sy(0), Sx(3), Sy(3), AA, BB)
        Call Cdiv(AA, BB, Sx(1), Sy(1), C, D) '(S11*S22)/S21
        Tx(0) = Sx(2) - C 'S12-((S11*S22)/S21)
        Ty(0) = Sy(2) - D
        Call Cdiv(Sx(0), Sy(0), Sx(1), Sy(1), Tx(2), Ty(2)) 'T12=S11/S21
        Call Cdiv(Sx(3), Sy(3), Sx(1), Sy(1), Tx(1), Ty(1)) 'T21=S22/S21
        Tx(1) = -1 * Tx(1) 'T21=-1*(S22/S21)
        Ty(1) = -1 * Ty(1)
        Call Cdiv(1, 0, Sx(1), Sy(1), Tx(3), Ty(3)) 'T22=1/S21
    End Sub
    Public Sub Cdiv(ByVal X1 As Double, ByVal Y1 As Double, ByVal X2 As Double, ByVal Y2 As Double, ByRef X3 As Double, ByRef Y3 As Double)
        Dim Denom As Double
        Denom = X2 * X2 + Y2 * Y2 'Multiplication by conjugate (X2+iY2)(X2-iY2)
        X3 = (X1 * X2 + Y1 * Y2) / Denom
        Y3 = (Y1 * X2 - X1 * Y2) / Denom
    End Sub
    Public Sub Cmult(ByVal X1 As Double, ByVal Y1 As Double, ByVal X2 As Double, ByVal Y2 As Double, ByRef X3 As Double, ByRef Y3 As Double)
        X3 = X1 * X2 - Y1 * Y2
        Y3 = X1 * Y2 + Y1 * X2
    End Sub
End Module