2012-10-09 10 views
5

Co kiedyś mieć:Korzystanie z ParamArray, ale wymagające co najmniej jeden parametr

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

Pierwszy z nich po prostu wywołuje drugi z {channel} do przekształcenia jej parametr do tablicy.

Zdecydowałem, że utworzenie listy kanałów do przekazania do tej metody było niezręczne i zdecydowałem się połączyć dwa przeciążenia w jedną metodę, która zajmuje ParamArray.

Public Sub Subscribe(ParamArray channels() As ChannelType) 

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

Co to jest "najlepsza praktyka" tutaj? Podoba mi się elastyczność, jaką daje mi ParamArray, pozwalając ludziom przekazywać rzeczy, ale nie pomaga to deweloperowi "działać bezawaryjnie" dzięki informowaniu o błędzie kompilatora ... oznacza to, że coś takiego jak ArgumentException jest tutaj wykluczone, ponieważ ludzie Spożywanie tej metody nie może oznaczać testów jednostkowych. Jeden opcji jest następujące ...

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

ale czuję, że stawia mnie prawie z powrotem do punktu wyjścia, jest kłopotliwe i wymaga mój wdrożenie tej metody jest mniej prosta.

Odpowiedz

11

Inną opcją do rozważenia byłoby

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()> tag z drugim parametrem True informuje kompilator, że próbuje wykorzystać znaczny sposób powinien R esult w błędzie kompilacji. Ponieważ dana metoda byłaby użyta wtedy i tylko wtedy, gdy podjęta zostanie próba wywołania metody bez parametrów, spowodowałaby błąd tylko w takich momentach. Zauważ, że metoda nie zostanie użyta, jeśli podjęto próbę przekazania metody zerowej tablicy elementarnej Integer; w takim przypadku użyty zostanie zwykły formularz ParamArray.

+0

To jest sprytne! –

+0

Myślę, że ta odpowiedź to ... przepraszam @ Meta-Knight! Podoba mi się, jak uzyskuję informację zwrotną od kompilatora i uzyskuję prostą łatwość użycia, mogąc po prostu powtórzyć "ParamArray" zamiast konieczności łączenia jednego elementu z "ParamArray", aby powtórzyć moje argumenty. –

+2

@JeffBridgman: Zauważ, że ten kod, w przeciwieństwie do podejścia z oddzielnym argumentem, umożliwia przekazywanie kodu w tablicy zawierającej wszystkie parametry, zamiast przechodzić pierwszy element i tablicę zawierającą resztę; w konsekwencji, podczas gdy może odrzucić wywołanie z pustą listą argumentów, nie może w czasie kompilacji odrzucić wywołania z pustą tablicą. – supercat

6

Myślę, że opcja, o której wspomniałeś, jest najlepszą opcją. Korzystanie wyraźniejsze nazwy dla swoich parametrów będzie to mniej mylące:

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

Inną opcją jest egzekwowanie go w czasie wykonywania, ale jak pan powiedział, że nie uda się tak szybko:

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 
+0

Dobra odpowiedź! Gdybym miał problem z domeną, w której był główny kanał i dodatkowe kanały, pierwsza wspomniana opcja byłaby idealna! –

Powiązane problemy