2010-04-14 11 views
6

Alcuni metodi predefiniti contengono uno ParamArray nella loro firma. I delegati, tuttavia, non possono contenere un ParamArray nella loro firma.Delegates and ParamArray - Suggerimenti per soluzioni alternative?

Domanda: Si supponga di voler creare un meccanismo di delega per un metodo specifico che richiede un ParamArray. Come faresti a risolvere questo vincolo?

MODIFICA: per chiarire, si supponga che non sia possibile modificare le firme del metodo (metodi predefiniti, definiti da terze parti, che si tratti di Microsoft o meno).

EDIT2: Il vero problema qui è mantenere lo zucchero sintassi, perché il seguente codice funziona, ma elimina lo zucchero:

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: Si scopre che le soluzioni di Skeet è applicabile anche per la creazione di Eventi e operatori contenenti un ParamArray.

risposta

17

Hmm ... funziona 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"); 
    } 
} 

Tuttavia, hai ragione - la dichiarazione delegato equivalente in VB non riesce:

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

Dà:

errore BC33009: i parametri "Delega" non possono essere dichiarati "ParamArray".

Curioso. Fortunatamente, c'è un modo intorno ad esso:

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 

Fondamentalmente ho solo applicato ParamArrayAttribute manualmente. Sembra funzionare bene.

Tuttavia, niente di tutto questo ti avrebbe impedito di utilizzare i metodi esistenti ParamArray. Questi metodi sono in grado di acquisire array normali, pertanto è possibile dichiarare i tipi di delegati come normali e creare ancora istanze delegate che fanno riferimento a tali metodi senza alcun problema. Il tipo di delegato influisce solo su come potresti chiamare il delegato.

Oltre a dichiarare un tipo di delegato con un array di parametri, non vedo realmente quale fosse il problema.

+0

Trovo interessante il fatto che funzioni bene se non si utilizza lo zucchero per aggiungere l'attributo ... limitazioni del compilatore sciocco FTL –

+0

Mai saputo che l'attributo esistesse nemmeno! –

+0

@Jon Skeet, hai ragione, l'unico vero problema qui è stato mantenere lo zucchero della sintassi, e ho aggiunto questa nota alla domanda stessa. Ancora una volta, la leggenda è all'altezza del suo nome. Grazie per aver risolto questo. –

0

Sei sicuro che i delegati non supportano ParamArray? Ok, anche se non lo fanno, ParamArray è lo zucchero della sintassi per un semplice vecchio array. definire parametro come array, questo è tutto.

Problemi correlati