2010-04-14 7 views
6

Algunos métodos predefinidos contienen un ParamArray en su firma. Los delegados, sin embargo, no pueden contener un ParamArray en su firma.Delegados y ParamArray: ¿Sugerencias de solución?

Pregunta: Supongamos que desea crear un mecanismo de delegación para un método específico que requiere un ParamArray. ¿Cómo trabajarías en esta restricción?

EDITAR: para dejar en claro, suponga que no puede cambiar las propias firmas de método (métodos predefinidos, definidos por un tercero, ya sea Microsoft o no).

Edit2: El verdadero problema aquí es mantener el azúcar en la sintaxis, debido a que el siguiente código funciona, pero elimina el azúcar:

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: Resulta que las soluciones de Skeet es aplicable también para la creación de Eventos y operadores que contienen un ParamArray.

Respuesta

17

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

Sin embargo, tienes razón - la declaración de delegado equivalente en VB falla:

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

Da:

error BC33009: los parámetros 'Delegado' no se pueden declarar 'ParamArray'.

Curious. Afortunadamente, hay una manera alrededor de ella:

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 

Básicamente he acaba de aplicar ParamArrayAttribute manualmente. Parece que funciona bien.

Sin embargo, nada de esto le habría impedido utilizar los métodos existentes ParamArray de todos modos. Esos métodos son bastante capaces de tomar arreglos normales, por lo que podría haber declarado sus tipos de delegados como normales y aún crear instancias delegadas que hicieran referencia a esos métodos sin ningún problema. El tipo de delegado solo afecta cómo podría llamar al delegado.

Aparte de declarar un tipo de delegado con una matriz de parámetros, realmente no veo cuál fue el problema.

+0

Me resulta intrigante que funciona bien si no usas el azúcar para agregar el atributo ... tontas limitaciones del compilador FTL –

+0

¡Nunca se supo que ese atributo existía siquiera! –

+0

@Jon Skeet, tienes razón, el único problema real aquí era mantener la sintaxis azucarada, y he agregado esta nota a la pregunta en sí. Una vez más, la leyenda hace honor a su nombre. Gracias por resolver esto. –

0

¿Está seguro de que los delegados no son compatibles con ParamArray? De acuerdo, incluso si no lo hacen, ParamArray es azúcar de sintaxis para una vieja matriz simple. define el parámetro como una matriz, eso es todo.