Делегаты и 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.

6
задан M.A. Hanin 15 November 2017 в 17:45
поделиться

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: 'Delegate' parameters cannot be declared '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. Эти методы вполне способны принимать обычные массивы - так что вы могли бы объявить свои типы делегатов как обычные и по-прежнему создавать экземпляры делегатов, которые ссылаются на эти методы, без каких-либо проблем. Тип делегата влияет только на то, как вы сможете вызывать делегат.

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

19
ответ дан 8 December 2019 в 12:18
поделиться

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

0
ответ дан 8 December 2019 в 12:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: