Использование ParamArray, но требуется хотя бы один параметр

Что у меня раньше было:

Public Sub Subscribe(channel As ChannelType)
Public Sub Subscribe(channels As IEnumerable(Of ChannelType))

Первый просто вызывает второй с {channel} преобразовать его параметр в массив.

Я решил, что создавать список каналов для передачи методу было неудобно, и решил объединить две перегрузки в один метод, который требует ParamArray,

Public Sub Subscribe(ParamArray channels() As ChannelType)

'Usage
Subscribe(ChannelType.News)
Subscribe(ChannelType.News, ChannelType.Sports)
Subscribe() 'Oops... this is valid

Что такое "лучшая практика" здесь? Мне нравится гибкость, которая ParamArray дает мне просто позволить людям передавать вещи, но это не может помочь разработчику "быстрее" через обратную связь об ошибках компилятора... это означает, что что-то вроде ArgumentException здесь не может быть и речи, так как люди, использующие этот метод, могут не писать никаких модульных тестов. Один из вариантов заключается в следующем...

Public Sub Subscribe(channel As ChannelType)
Public Sub Subscribe(channel As ChannelType, ParamArray channels() As ChannelType)

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

2 ответа

Решение

Другой вариант для рассмотрения будет

Module ParamArrayTest
    Sub ShowThings(ParamArray MyThings() As Integer)
        For Each thing As Integer In MyThings
            Debug.Print("{0}", thing)
        Next
    End Sub

    ' Don't try to call without parameters:
    <Obsolete("Must have at least one parameter", True)> Sub ShowThings()
        Throw New ArgumentException("Must specify at least one parameter")
    End Sub

    Sub Test()
        ShowThings(3, 4, 5)
        ShowThings()
    End Sub
End Module

<Obsolete()> тег со вторым параметром True сообщает компилятору, что попытка использовать помеченный метод должна привести к ошибке компиляции. Поскольку рассматриваемый метод будет использоваться тогда и только тогда, когда будет предпринята попытка вызвать метод без каких-либо параметров, он вызовет ошибку только в такие моменты времени. Обратите внимание, что метод не будет использоваться, если будет сделана попытка передать метод массиву с нулевым элементом Integer; в этом случае нормальный ParamArray Форма будет использоваться.

Я думаю, что вариант, который вы упомянули, является лучшим вариантом. Использование более четких имен для ваших параметров сделает его менее запутанным:

Public Sub Subscribe(mainChannel As ChannelType, ParamArray otherChannels() As ChannelType)

Другой вариант - применить его во время выполнения, но, как вы сказали, он не потерпит неудачу так быстро:

Public Sub Subscribe(ParamArray channels() As ChannelType)
    If channels.Count = 0 then
        Throw new InvalidOperationException("At least one channel is needed")
    End If
End Sub
Другие вопросы по тегам