我曾经拥有的东西:
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)
但我觉得这让我几乎回到原点,令人困惑,并要求我对该方法的实施不那么简单。
答案 0 :(得分: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
带有第二个参数<Obsolete()>
的{{1}}标记通知编译器尝试使用标记方法会导致编译错误。由于当且仅当尝试在没有任何参数的情况下调用该方法时,将使用所讨论的方法,因此仅在这些时间引起错误。请注意,如果尝试将方法传递给True
的零元素数组,则不会使用该方法;在这种情况下,将使用正常的Integer
形式。
答案 1 :(得分:6)
我认为您提到的选项是最佳选择。为参数使用更清晰的名称会减少混淆:
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