BestPractices: параметры Out против сложных возвращаемых типов в методах - PullRequest
2 голосов
/ 21 января 2011

Используя сложный тип возврата:

Public Type TimeType
    hours As Integer
    minutes As Integer
End Type

Public Function ParseTimeField(time As String) As TimeType
    Dim timeObject As TimeType
    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

Вызов:

Dim timeObj As TimeType
timeObj = ParseTimeField(strTime)

ИЛИ используя параметры:

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

Вызов:

Dim hours As Integer
Dim minutes As Integer

Call ParseTimeField(strTime, hours, minutes)

Кстати, это код VB6 =)

Ответы [ 4 ]

3 голосов
/ 21 января 2011

Если у вас один возвращаемый тип, не используйте параметр out для его возврата.

В общем, я считаю, что несколько параметров ref / out являются запахом кода. Если вам нужно вернуть данные из вашего метода, лучше, если они находятся в одном связном объекте.

2 голосов
/ 21 января 2011

У меня есть ощущение, что мы увидим разные мнения по этому вопросу.Не уверен, что существует лучшая практика.

Я обычно предпочитаю сложные типы данных, потому что я чувствую, что это больше соответствует исходной структуре функций, где выходной параметр предшествовал входным параметрам в сигнатуре.По сути, мне не нравятся параметры - они излишни.Всякий раз, когда есть два способа сделать что-то на языке программирования, вы усложняете ненужное (думаю, я буду убит фанатами Perl, утверждающими это).Вы возвращаете данные с помощью оператора return.Period.

Это говорит о том, что я все еще часто использую параметры, когда мне нужно вернуть два параметра, которые не имеют естественной группировки - т.е. оказались бы в классе, который будет использоваться исключительно в возвращаемом значении этогоконкретная функция.

Всякий раз, когда в возвращаемых данных есть три или более параметров, я никогда не использую их просто потому, что нахожу вызывающий код слишком многословным - мне нужно затемнить переменные (или var'em в C #)

1 голос
/ 21 января 2011

Я склонен использовать params как универсальный стиль.Редко нужно реализовывать вспомогательные функции, которые возвращают UDT, но обычно они являются частными для модуля, поэтому я также могу оставить область действия UDT приватной для модуля.*

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

... и, скорее всего, сохранит TimeType в закрытой области видимости.

0 голосов
/ 21 января 2011

Определенно вопрос мнения. Время от времени я использую ByRef параметры, особенно для служебных функций, которые требуют сценария типа успех / неудача. Например, функции TryParse в .net framework делают именно это. Ваша параметризованная функция может выглядеть так:

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

То есть вы можете назвать это как:

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

Однако, когда все становится более сложным, и вы на самом деле возвращаете бизнес-элементы, а не выполняете логические команды, тогда более желательны отдельный класс и тип возврата. Это также облегчает обслуживание звонков и возвратов.

...