提问人:Scot 提问时间:6/24/2023 最后编辑:Peter SeligerScot 更新时间:6/25/2023 访问量:102
尝试从函数返回数组
Trying to return array from function
问:
我一直在努力寻找解决方案。我以为我有这个权利,但发生了错误。“System.Array 类型的值无法转换为 Decimal。
我正在尝试从我的函数返回 2 个数字。一个是整数,另一个是十进制,但我只是将 int 转换为小数并尝试将其添加到我创建的数组中。这是我的部分代码:
Public Function CalcMaxBal(ByVal maxbal As Decimal, ByVal npmts As Int16, ByVal starttype As Int16, ByVal startrate As Decimal, ByVal startper As Int16, ByVal pmtadjcap As Decimal, ByVal pmtadjper As Int16, ByVal origrate As Decimal, ByVal noterate As Decimal, ByVal origbal As Decimal, ByVal totpmts As Int16, ByVal extra As Decimal, ByVal extraper As Int16, ByVal io As Int16, ByVal iocb As Boolean, ByVal miamt As Decimal) As Array
'this function is only called for a bi-weekly payment computation
Dim rpmt As Decimal=255
Dim per as Decimal =4
Dim result(2) As Decimal
result(0) = rpmt
result(1) = per
Return result
这是代码的关键元素。这是行不通的。result 是一个包含 2 位小数的数组。为什么 vb.net 不承认这一点?我在委托中说,我要返回一个数组,这就是我要返回的数组。是否可以在数组中返回一个小数点,或者必须通过公共类来完成?
答:
您可以返回一个(命名的)元组而不是数组。
基本上,声明函数是这样的:
Function X(a As Integer) As (RPmt As Decimal, Per As Decimal)
Dim r = 1.2D
Dim p = 0.2D
Return (Rpmt:=r, Per:=p)
End Function
并以这种方式使用它:
Dim y = X(1)
Console.WriteLine(y.Per & ", " & y.RPmt)
您可以看到使用了元组项的名称,而不是数组索引。它使查看要使用的项变得更加容易,而不必记住每个部分在哪个数组索引中。
源代码的重要部分是易于正确编写和易于维护。避免使用“幻数”有助于实现这些目标。
请注意,使用 Option Infer On
时,无需声明 (在示例中) 的类型,编译器会为您找出它。y
评论
因此,您希望从公共函数/方法返回复合值(两个十进制值的笛卡尔乘积)。
安德鲁·莫顿(Andrew Morton)关于对该复合值使用元组类型而不是数组类型的回答确实是一个很大的改进,因为您将更清楚地了解从函数返回的特定数据结构。
但是,由于(命名)元组在提高代码可读性方面做得并不好,因此我个人更愿意将其定义限制在相对较小的范围内,以便轻松监督它们的使用。(就像在类的私有实现中一样。
在您的方案中 - 可以从代码中的任何位置调用的公共函数 - 返回的值也可以有效地用于任何地方。在所有这些地方,必须一遍又一遍地指定该(命名)元组类型的结构。对于想要调用您的公共函数的开发人员(包括您自己)来说,这不是很方便。
因此,在这样的场景中,我会做更多的工作,以便调用公共函数的所有客户端代码都更加简洁明了:我将定义并使用 DTO 类或结构(例如命名)而不是元组。然后,在调用公共函数的所有位置,将使用该类型而不是(命名)元组来处理其返回值。MaxBalInfo
MaxBalInfo
Public Class MaxBalInfo
Public Property RPmt As Decimal
Public Property Per As Decimal
End Class
...
Public Function CalcMaxBal(...) As MaxBalInfo
'this function is only called for a bi-weekly payment computation
Dim rpmt As Decimal = 255
Dim per as Decimal = 4
...
Return New MaxBalInfo With
{
.RPmt = rpmt
.Per = per
}
End Function
顺便说一句,我认为讨论“类与结构”(或实际上是“值类型与引用类型”)在这里是偏离主题的。我在这里对类(引用类型)而不是结构(值类型)的选择是任意的。但请注意,当您选择元组类型时,您也会隐式选择值类型。由您决定相应的行为差异是否正确适合您的软件设计。
评论
Public Function CalcMaxBal() As Decimal()
Array
Shared
Decimal()
Decimal
Array