使用ParamArray,但至少需要一个参数

Jef*_*f B 5 vb.net parameters paramarray

我曾经拥有的:

Public Sub Subscribe(channel As ChannelType)
Public Sub Subscribe(channels As IEnumerable(Of ChannelType))
Run Code Online (Sandbox Code Playgroud)

第一个只调用第二个{channel}将其参数转换为数组.

我决定必须创建一个传递给方法的通道列表是很尴尬的,并选择将两个重载组合成一个需要a的方法ParamArray.

Public Sub Subscribe(ParamArray channels() As ChannelType)

'Usage
Subscribe(ChannelType.News)
Subscribe(ChannelType.News, ChannelType.Sports)
Subscribe() 'Oops... this is valid
Run Code Online (Sandbox Code Playgroud)

这里的"最佳实践"是什么?我喜欢灵活性,这ParamArray让我只是让人们传递内容,但它无法通过编译器错误反馈帮助开发人员"失败更快"...这意味着像这样的东西ArgumentException是不可能的,因为人们消费这个方法可能不会编写任何单元测试.一个选项是以下......

Public Sub Subscribe(channel As ChannelType)
Public Sub Subscribe(channel As ChannelType, ParamArray channels() As ChannelType)
Run Code Online (Sandbox Code Playgroud)

但我觉得这让我几乎回到原点,令人困惑,并要求我对这种方法的实施不那么直截了当.

sup*_*cat 12

另一个需要考虑的选择是

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
Run Code Online (Sandbox Code Playgroud)

<Obsolete()>带有第二个参数的标记True通知编译器尝试使用标记的方法应该导致编译错误.由于当且仅当尝试在没有任何参数的情况下调用该方法时,将使用所讨论的方法,因此仅在这些时间引起错误.注意,如果尝试将方法传递给零元素数组,则不会使用该方法Integer; 在这种情况下,ParamArray将使用正常形式.

  • @JeffBridgman:请注意,与具有单独参数的方法不同,此代码使代码可以传入包含所有参数的数组,而不必传递第一个项和包含其余项的数组; 因此,虽然它可以禁止使用空参数列表进行调用,但它不能在编译时禁止使用空数组进行调用. (2认同)

Met*_*ght 6

我认为你提到的选项是最好的选择.为参数使用更清晰的名称将减少混淆:

Public Sub Subscribe(mainChannel As ChannelType, ParamArray otherChannels() As ChannelType)
Run Code Online (Sandbox Code Playgroud)

另一种选择是在运行时强制执行它,但正如你所说的那样,它不会那么快失败:

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
Run Code Online (Sandbox Code Playgroud)