开发者

BestPractices: Out parameters vs complex return types in methods

Using complex return type:

Public Type TimeType
    hours As Integer
    minutes As Integer
End Type

Public Function ParseTimeField(time As String) As TimeType
    Dim timeObject As TimeT开发者_如何学编程ype
    Dim amountOfDigitHours As Integer

    If time = "" Then time = "0"

    If HasHoursAndMinutesParts(time) Then
        amountOfDigitHours = GetAmountOfDigitHours(time)
        timeObject.hours = CInt(Left(time, amountOfDigitHours))
        timeObject.minutes = CInt(Right(time, 2))
    Else
        timeObject.hours = 0
        timeObject.minutes = CInt(time)
    End If

    ParseTimeField = timeObject
End Function

Private Function HasHoursAndMinutesParts(time As String) As Boolean
    HasHoursAndMinutesParts = Len(time) > 2
End Function

Private Function GetAmountOfDigitHours(time As String) As Integer
    GetAmountOfDigitHours = Len(time) - 2
End Function

Call:

Dim timeObj As TimeType
timeObj = ParseTimeField(strTime)

OR using out parameters:

Public Function ParseTimeField(time As String, ByRef hours As Integer, ByRef minutes As Integer)
    Dim timeObject As TimeType
    Dim amountOfDigitHours As Integer

    If time = "" Then time = "0"

    If HasHoursAndMinutesParts(time) Then
        amountOfDigitHours = GetAmountOfDigitHours(time)
        hours = CInt(Left(time, amountOfDigitHours))
        minutes = CInt(Right(time, 2))
    Else
        hours = 0
        minutes = CInt(time)
    End If

    ParseTimeField = timeObject
End Function

Private Function HasHoursAndMinutesParts(time As String) As Boolean
    HasHoursAndMinutesParts = Len(time) > 2
End Function

Private Function GetAmountOfDigitHours(time As String) As Integer
    GetAmountOfDigitHours = Len(time) - 2
End Function

Call:

Dim hours As Integer
Dim minutes As Integer

Call ParseTimeField(strTime, hours, minutes)

BTW this is VB6 code =)


If you have a single return type, do not use an out parameter to return it.

In general, I find multiple ref/out parameters to be a code smell. If you need to return data from your method, it is better if it is in one coherent object.


I have a feeling we're going to see different opinions on this matter. Not sure there exists a best practice.

I usually prefer complex datatypes because I feel that is more in line with the original structure of functions where output parameter preceed the input parameters in the signature. Basically I don't like out parameters - they're superfluous. Whenever there's two ways of doing a thing in a programming language, you complicate unneccessary (guess I'm gonna get killed by Perl-fanatics stating this). You return data with the return statement. Period.

This said, I still find myself using out parameters often when I need to return two parameteres that have no natural grouping - i.e. would end up in a class which would be used solely in the return value of this specific function.

Whenever there's three or more parameters in the return data, I never use out simply because I find the calling code to be excessive verbose - needing to Dim the variables (or var'em in C#)


I tend to use out params as the universal style. Rarely need to implement helper functions that return UDT but these are usually private to the module so I can keep the scope of the UDT private to the module too.

In the latter case usually consume the retval like this

With ParseTimeField(strTime)
    Debug.Print .hours, .minutes
End With

... and most probably would keep TimeType with private scope.


Definately a matter of opinion. I do use ByRef parameters from time to time, especially for utility functions which require a success/fail type scenario. For example, the TryParse functions in the .net framework do exactly this. Your parametrised function could look like:

Public Function ParseTimeField(time As String, ByRef hours As Integer, ByRef minutes As Integer) As Boolean
    'Do stuff'
    ParseTimeField = True 'or false depending on output success'
End Sub

Meaning you can call it like:

Dim hours As Integer
Dim mins as Integer
If ParseTimeField(time, hours, mins) = True Then
    'It worked'
End If

However as things start to get more complicated, and you're actually returning business items as opposed to doing logical commands, then a separate class and a return type is more desirable. It also makes calling AND returning easier to maintain.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜