Saturday, April 17, 2010

ParamArray used with Delegates, Events and Operators

ParamArray is a method-signature syntax sugar, used for passing an array of arguments without explicitly creating an array. It is quite tastey:
  1. Public Sub SomeSub(ByVal ParamArray Arguments() As String)  
  2.   For Each arg In Arguments  
  3.       Console.WriteLine(arg)  
  4.   Next  
  5. End Sub  
  6.   
  7. Sub Main()  
  8.   SomeSub("ParamArray""is""sweet")  
  9. End Sub  
Problem:

Trouble arises when you try to combine a ParamArray with Delegates, Events or Operators:
  1. Public Delegate Sub SomeDelegate(ByVal ParamArray Arguments As String)  
  2. Public Event SomeEvent(ByVal ParamArray EventArguments As String)  
  3. Public Overloads Shared Operator +(ByVal a As Class1, ByVal ParamArray b As Class1) As Class1  

Trying to use any of these will cause the following error:
BC33009: <type> parameters cannot be declared 'ParamArray'
(where <type> is either Event, Delegate or Operator)

With Delegates, you can always create the delegate with an Array argument instead of the ParamArray, but this takes off the syntax sugar as you have to explicitly create and pass an array when invoking the Delegate.

So how do we create Delegates, Events and Operators with ParamArray, for keeping the syntax sugar?

Solution:

Instead of using the ParamArray keyword, use the ParamArrayAttribute, as follows:
  1. Public Delegate Sub SomeDelegate(<[ParamArray]()> ByVal Arguments As String)  
  2. Public Event SomeEvent(<[ParamArray]()> ByVal EventArguments As String)  
  3. Public Overloads Shared Operator +(ByVal a As Class1, <[ParamArray]()> ByVal b As Class1) As Class1  

Credit:
The solution to this issue was brought to me by the legendary Jon Skeet, at this StackOverflow post.

1 comment:

  1. How about invoke?
    Me.invoke(New SomeDelegate(AddressOf SomeFunction), Arguments)

    ????

    ReplyDelete