Делегаты и ParamArray - предложения обойти? - PullRequest
6 голосов
/ 14 апреля 2010

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

Ответы [ 2 ]

19 голосов
/ 14 апреля 2010

Хмм ... это работает в 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 голосов
/ 14 апреля 2010

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

...