1

I have been trying to find a solution. I thought that I had this right but an error occurs. "Value of type System.Array cannot be converted to Decimal. "

I'm trying to return 2 numbers from my function. One is an integer and the other is a decimal but I"m just converting the int to a decimal and trying to add it to the array I created. Here's a portion of my code:

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

This is the crucial elements of the code. It doesn't work. result is an array of 2 decimals. Why doesn't vb.net recognize this? I said in the delegate that I"m returning an array which is what I'm returning. Is it possible to return one integer a decimal in an array or would that have to be done via a public class?

5
  • I was actually able to figure out the problem. My function is ok. but I was calling the function with : Decimal value = call to function. I have changed it to an Array value= call to the function and it is working now. I am getting both numbers returned. Commented Jun 23, 2023 at 23:46
  • 2
    Why not simply declare the return to be a decimal array? Public Function CalcMaxBal() As Decimal()? Why declare the return to be the abstract base class System.Array? Commented Jun 23, 2023 at 23:46
  • You should pretty much NEVER use the Array class directly, except for calling Shared methods to manipulate array objects. ALWAYS specify the type of the array. You are creating a Decimal() inside the method so what possible reason could there be for not declaring the return type of the method to be the same? Any code that used the result you have would have to do extra work to get values of type Decimal from that Array object. Commented Jun 24, 2023 at 6:40
  • Thanks for your comment. I see what you're saying. I guess the "extra work" slows things down. I want to keep things going fast. Does the length of variable names really cut into the time it takes to process the code? Commented Jun 26, 2023 at 17:56
  • This question is similar to: Return 2 values from function vb.net. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented May 17 at 14:31

3 Answers 3

3

You could return a (named) Tuple instead of an array.

Basically, declare the function something like this:

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

And use it in this fashion:

Dim y = X(1)
Console.WriteLine(y.Per & ", " & y.RPmt)

You can see that the names of the tuple item were used instead of an array index. It makes it much easier to see which item you're meant to be using instead of having to remember which array index each part is in.

Important parts of source code are ease of writing it correctly in the first place and ease of maintenance. Avoiding the use of "magic numbers" contributes to those.

Note that with Option Infer On there is no need to declare the type of y (in the example)—the compiler will figure it out for you.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for the explanation on tuple. I have not used this one before. I will test it out.
0

So you want to return a composite value (a Cartesian product of two decimal values) from your public function/method.

Andrew Morton's answer about using a tuple type instead of an array type for that composite value is a great improvement indeed, since you would be more clear about the specific data structure that you return from your function.

However, because (named) tuples do not do a great job on improving code readability, I personally prefer to limit their definitions to relatively small scopes, in which their usage can be easily overseen. (Like within the private implementation of classes.)

In your scenario - a public function that could be called from anywhere in your code - the returned value could effectively be used anywhere as well. In all those places, the structure of that (named) tuple type has to be specified over and over again. That's not very convenient for the developers (including yourself) who want to call your public function.

So, in scenarios like these, I would do a little more work, so that all client code that invokes your public function will be somewhat more concise and clear: I would define and use a DTO class or structure (named MaxBalInfo for example) instead of a tuple here. Then in all places where your public function is called, the MaxBalInfo type will be used instead of a (named) tuple for processing its return value.

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

By the way, I consider the discussion "class vs structure" (or actually "value type vs reference type") to be off-topic here. My choice for a class (reference type) over a structure (value type) is arbitrary here. But note that when you choose for a tuple type, that you also implicitly choose for a value type. It's up to you to decide if the corresponding difference in behavior will correctly fit into your software design.

1 Comment

Hi, thanks for the info Bart. I just want to get the 2 numbers as easily as possible. I will implement the tuple method in the future when I need more information returned. It could come in handy.
0

You can get return array values using ByRef in Sub.

    Dim result(2) As Decimal
    Public Sub CalcMaxBal(ByRef result() As Decimal, 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) 

        'this function is only called for a bi-weekly payment computation
        Dim rpmt As Decimal = 255
        Dim per As Decimal = 4

        result(0) = rpmt
        result(1) = per

    End Sub

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.