Delegates and ParamArray - Workaround Suggestions?

2020-04-05 18:58发布

问题:

Some predefined methods contain a ParamArray in their signature. Delegates, however, cannot contain a ParamArray in their signature.

Question: Assume you wish to create a delegation mechanism for a specific method which requires a ParamArray. How would you work around this constraint?

EDIT: just to make clear, assume you cannot change the method signatures themselves (pre-defined methods, defined by some 3rd party, be it Microsoft or not).

EDIT2: The real deal here is keeping the syntax sugar, because the following code does work, but eliminates the sugar:

Public Delegate Sub MyDelegate(ByVal myArgs() As Object)

Public Sub PredefinedSub(ByVal ParamArray myArgs() As Object)
    '...'
End Sub

Sub Test()
    Dim aDelegate As New MyDelegate(AddressOf PredefinedSub)
    aDelegate.Invoke(New Object() {1, 2, 3, 4})
End Sub

EDIT3: It turns out that Skeet's solutions is applicable also for creating Events and Operators containing a ParamArray.

回答1:

Hmm... it works in C#:

using System;

class Test
{
    delegate void Foo(params string[] args);

    static void Main()
    {
        Foo f = x => Console.WriteLine(x.Length);

        f("a", "b", "c");
    }
}

However, you're right - the equivalent delegate declaration in VB fails:

Delegate Sub Foo(ParamArray ByVal args() As String)

Gives:

error BC33009: 'Delegate' parameters cannot be declared 'ParamArray'.

Curious. Fortunately, there's a way round it:

Imports System

Public Class Test

    Delegate Sub Foo(<[ParamArray]()> ByVal args() As String)

    Public Shared Sub Main()
        Dim f As Foo = AddressOf PrintLength
        f("a", "b", "c")
    End Sub

    Private Shared Sub PrintLength(ByVal x() As String)
        Console.WriteLine(x.Length)
    End Sub

End Class

Basically I've just applied ParamArrayAttribute manually. Seems to work fine.

However, none of this would have stopped you from using existing ParamArray methods anyway. Those methods are quite capable of taking normal arrays - so you could have declared your delegate types as normal and still created delegate instances which referred to those methods with no problems at all. The delegate type only affects how you would be able to call the delegate.

Other than declaring a delegate type with a parameter array, I don't really see what the issue was.



回答2:

Are you sure that delegates do not support ParamArray? Ok, even if they don't, ParamArray is syntax sugar for plain old array. define parameter as array, that's it.