2010-04-14 5 views
6

Некоторые предопределенные методы содержат ParamArray в их подписи. Делегаты, однако, не могут содержать ParamArray в своей подписи.Делегаты и ParamArray - Временные решения?

Вопрос: Предположим, вы хотите создать механизм делегирования для определенного метода, который требует ParamArray. Как бы вы справились с этим ограничением?

РЕДАКТИРОВАТЬ: только чтобы уточнить, предположим, что вы сами не можете изменить сами сигнатуры метода (предопределенные методы, определенные сторонней стороной, будь то Microsoft или нет).

EDIT2: Реальные сделки здесь держит синтаксический сахар, потому что следующий код работает, но исключает сахар:

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: Оказывается, что решения по тарелочкам применимы также для создания События и операторы, содержащие параметр ParamArray.

ответ

17

Хм ... это работает в 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"); 
    } 
} 

Однако, вы правы - эквивалент заявление делегата в VB не удается:

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

Дает:

ошибка BC33009: параметры «делегата» не могут быть объявлены «ParamArray».

Любопытный. К счастью, есть способ вокруг него:

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 

В основном я просто применять ParamArrayAttribute вручную. Кажется, хорошо работает.

Однако все это ни в коем случае не остановило бы вас от использования существующих методов ParamArray. Эти методы вполне способны принимать нормальные массивы, поэтому вы могли бы объявить свои типы делегатов как обычные и все еще созданные экземпляры делегатов, которые ссылались на эти методы без каких-либо проблем. Тип делегата влияет только на то, как вы могли бы назвать делегата.

Помимо объявления типа делегата с массивом параметров, я действительно не понимаю, в чем проблема.

+0

Я нахожу его интригующим, что он отлично работает, если вы не используете сахар для добавления атрибута ... Глупые ограничения компилятора FTL –

+0

Никогда не знал, что этот атрибут существует даже! –

+0

@ Jon Skeet, вы правы, единственная реальная проблема здесь заключалась в том, чтобы сохранить синтаксический сахар, и я добавил эту заметку к самому вопросу. И снова легенда оправдывает свое название. Спасибо, что решили. –

0

Вы уверены, что делегаты не поддерживают ParamArray? Хорошо, даже если они этого не делают, ParamArray - синтаксический сахар для простого старого массива. определить параметр как массив, вот и все.