Делегаты и ParamArray - предложения обойти?
Некоторые предопределенные методы содержат ParamArray в своей подписи. Однако делегаты не могут содержать ParamArray в своей подписи.
Вопрос: Предположим, вы хотите создать механизм делегирования для конкретного метода, который требует ParamArray. Как бы вы обойти это ограничение?
РЕДАКТИРОВАТЬ: просто чтобы прояснить, предположим, что вы не можете изменить сигнатуры метода сами (предопределенные методы, определенные какой-либо третьей стороной, будь то Microsoft или нет).
РЕДАКТИРОВАТЬ 2: Реальная сделка здесь состоит в том, чтобы сохранить синтаксис сахар, потому что следующий код работает, но устраняет сахар:
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 ответа
Хм... это работает в 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
методы в любом случае. Эти методы вполне способны принимать обычные массивы - так что вы могли бы объявить ваши типы делегатов как нормальные и по-прежнему создавать экземпляры делегатов, которые ссылались на эти методы без проблем вообще. Тип делегата влияет только на то, как вы сможете вызвать делегата.
Кроме объявления типа делегата с массивом параметров, я действительно не вижу, в чем проблема.
Вы уверены, что делегаты не поддерживают ParamArray? Хорошо, даже если они этого не делают, ParamArray является синтаксическим сахаром для простого старого массива. определить параметр как массив, вот и все.