尝试从函数返回数组

Trying to return array from function

提问人:Scot 提问时间:6/24/2023 最后编辑:Peter SeligerScot 更新时间:6/25/2023 访问量:102

问:

我一直在努力寻找解决方案。我以为我有这个权利,但发生了错误。“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 不承认这一点?我在委托中说,我要返回一个数组,这就是我要返回的数组。是否可以在数组中返回一个小数点,或者必须通过公共类来完成?

数组 vb.net

评论

0赞 Scot 6/24/2023
我实际上能够弄清楚问题所在。我的功能还可以。但我用以下命令调用函数:十进制值 = 调用函数。我已将其更改为对函数的 Array value= 调用,它现在正在工作。我得到了两个号码的返回。
2赞 dbc 6/24/2023
为什么不简单地将返回值声明为十进制数组? ?为什么要将返回值声明为抽象基类 System.Array?Public Function CalcMaxBal() As Decimal()
0赞 jmcilhinney 6/24/2023
你几乎不应该直接使用这个类,除了调用方法来操作数组对象。ALWAYS 指定数组的类型。您正在创建一个内部方法,那么有什么可能的原因不声明方法的返回类型相同?使用您拥有的结果的任何代码都必须执行额外的工作才能从该对象获取类型的值。ArraySharedDecimal()DecimalArray
0赞 Scot 6/27/2023
感谢您的评论。我明白你在说什么。我想“额外的工作”会减慢速度。我想让事情快速进行。变量名称的长度真的会减少处理代码所需的时间吗?

答:

2赞 Andrew Morton 6/24/2023 #1

您可以返回一个(命名的)元组而不是数组。

基本上,声明函数是这样的:

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

评论

1赞 Scot 6/27/2023
感谢您对元组的解释。我以前没有用过这个。我会测试一下。
0赞 Bart Hofland 6/25/2023 #2

因此,您希望从公共函数/方法返回复合值(两个十进制值的笛卡尔乘积)。

安德鲁·莫顿(Andrew Morton)关于对该复合值使用元组类型而不是数组类型的回答确实是一个很大的改进,因为您将更清楚地了解从函数返回的特定数据结构。

但是,由于(命名)元组在提高代码可读性方面做得并不好,因此我个人更愿意将其定义限制在相对较小的范围内,以便轻松监督它们的使用。(就像在类的私有实现中一样。

在您的方案中 - 可以从代码中的任何位置调用的公共函数 - 返回的值也可以有效地用于任何地方。在所有这些地方,必须一遍又一遍地指定该(命名)元组类型的结构。对于想要调用您的公共函数的开发人员(包括您自己)来说,这不是很方便。

因此,在这样的场景中,我会做更多的工作,以便调用公共函数的所有客户端代码都更加简洁明了:我将定义并使用 DTO 类或结构(例如命名)而不是元组。然后,在调用公共函数的所有位置,将使用该类型而不是(命名)元组来处理其返回值。MaxBalInfoMaxBalInfo

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

顺便说一句,我认为讨论“类与结构”(或实际上是“值类型与引用类型”)在这里是偏离主题的。我在这里对类(引用类型)而不是结构(值类型)的选择是任意的。但请注意,当您选择元组类型时,您也会隐式选择值类型。由您决定相应的行为差异是否正确适合您的软件设计。

评论

0赞 Scot 6/27/2023
嗨,感谢您提供的信息巴特。我只想尽可能轻松地获得 2 个数字。当我将来需要返回更多信息时,我将实现元组方法。它可能会派上用场。