Func(Of Tin, Tout) с использованием лямбда-выражения с аргументом ByRef дает несовместимую ошибку подписи

Почему это:

Private [Function] As Func(Of Double, String) = Function(ByRef z As Double) z.ToString

дает следующую ошибку:

Вложенная функция не имеет подписи, совместимой с делегатом String)'.

Пока это:

Private [Function] As Func(Of Double, String) = Function(ByVal z As Double) z.ToString

Не? (Разница ByRef/ByVal)

Кроме того, как я могу реализовать такую ​​​​вещь?


person Brian Mulcahy    schedule 09.03.2011    source источник


Ответы (2)


Вы получаете эту ошибку, поскольку тип делегата Функция (ByVal z As Double) As String не совместим с Функция (ByRef z As Double) As String. Вам нужно точное совпадение.

Также вы не можете объявить общий делегат Func(Of ...) с параметрами ByRef (ref или out в C#), независимо от того, вы используете анонимную функцию или нет.

Но вы можете объявить свой тип делегата, а затем использовать его даже со своей анонимной функцией.

Delegate Function ToStringDelegate(ByRef value As Double) As String

Sub Main()
    Dim Del As ToStringDelegate = Function(ByRef value As Double) value.ToString()
End Sub

или вы можете использовать неявную типизацию (если Option Infer включен)

Dim Del = Function(ByRef value As Double) value.ToString()
person Tom Kris    schedule 09.03.2011

В MSDN упоминаются следующие правила, применяемые к области видимости переменных в лямбда-выражениях:

  • Захваченная переменная не будет удалена сборщиком мусора до тех пор, пока ссылающийся на нее делегат не выйдет из области видимости.
  • Переменные, введенные в лямбда-выражение, не видны во внешнем методе.
  • Лямбда-выражение не может напрямую получить ссылку [ByRef в VB] или выходной параметр из включающего метода.
  • Оператор return в лямбда-выражении не приводит к возврату вложенного метода.
  • Лямбда-выражение не может содержать оператор goto, оператор break или оператор continue, цель которого находится вне тела или в теле содержащейся анонимной функции.
person Matt    schedule 09.03.2011