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

Arrays 将数组变量和其他变量传入和传出VB.Net子例程方法,arrays,vb.net,methods,parameter-passing,subroutine,Arrays,Vb.net,Methods,Parameter Passing,Subroutine,我正在将代码从VB6转录到VB.Net表单,该代码处理复数数组。语言语法变得更加严格,我非常仔细地研究了ByVal和ByRef关键字的使用,这样我就不能根据需要更改或更改通过方法子例程的变量。然而,VB6似乎允许我将空变量传递到子例程中,并在调用行中接收更改的(内部计算的)变量。Net似乎不允许将空变量作为规则传递到方法子例程中?在我下面分享的代码片段中,我只能通过任意设置初始值来避免调用null异常,这些参数实际上是在方法子例程中定义的。有没有办法避免这种不雅的开销 Module Mo

我正在将代码从VB6转录到VB.Net表单,该代码处理复数数组。语言语法变得更加严格,我非常仔细地研究了ByVal和ByRef关键字的使用,这样我就不能根据需要更改或更改通过方法子例程的变量。然而,VB6似乎允许我将空变量传递到子例程中,并在调用行中接收更改的(内部计算的)变量。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分量的单独数组(在主方法中)。我知道数组在VB.Net中自动被赋予引用类型,因此不需要在被调用的子程序StoT中将传递的参数定义为ByVal或ByRef。我再次重复:通过在主定义中为输出参数Tx()和Ty()预先定义任意值,我只能使这个调用工作,而不会在StoT中调用null异常。
为了完成所需的算术任务,方法StoT需要执行在方法子例程CDiv()和CMult()中编码的复数除法和复数乘法任务。同样,这些函数接受并提供输出双精度数字,这符合以下规则,即数字只能使用ByRef关键字作为输出数字提供。但是,这些调用不会调用null异常,即使它们生成的应答复数不是预先存在的。所以我的问题是为什么会这样。似乎存在不一致性……

我早就忘记了这在VB6中是否有不同的工作方式,但在.NET中,当您传递数组ByRef时,可以将参数分配给调用方法中完全不同的数组。因此,如果不传入任何内容,则可以分配一个新数组并将新数组分配给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

对不起,我不明白。如果这段代码有效,你会做什么改变,使它引发一个空引用异常?谢谢,这有点帮助,但实际上在生活中,在一个问题之前,从来没有一个答案!似乎我必须提出任意数字,就像占位符一样,才能使代码起作用。然而,空引用似乎传递到方法CDiv()和CMult(),答案作为方程的解计算,并作为双精度变量传递给ByRef。我还不能说你已经回答了我的问题。Double是一种值类型,因此不能是空的。Double总是初始化为0,因此总是为您分配了要写入的存储空间。Double数组是一种引用类型,如果设置为Nothing,那么就没有分配给您的内存来写入值。好的-实际上它在VB.6中是这样工作的,但是我想一定有一些问题需要在VB.Net中实现更严格的方法?