Я хотел бы иметь функцию, которая может «обернуть» любой другой вызов функции. В этом конкретном случае это позволило бы мне написать более общую обработку транзакций вокруг некоторых конкретных операций.Использование дженериков в dotnet для функций с любым количеством аргументов?
Я могу написать это для любого определенного количества аргументов, например. для одного аргумента:
Public Shared Sub WrapFunc(Of T)(ByVal f As Action(Of T), ByVal arg As T)
' Test some stuff, start transaction
f(arg)
' Test some stuff, end transaction
End Sub
... но я надеялся, чтобы это обрабатывать любое количество аргументов, без необходимости иметь дублированный код 0 аргументов, 1 ARG, 2 арг и т.д.
Есть способ сделать это?
[Изменить] Спасибо Роберту Фрейзеру за код C#. Для справки, вот перевод на VB:
[Edit2] Исправленный код. К сожалению, похоже, что нет возможности использовать отдельные функции ActAsFunc в vb. С положительной стороны, они скрыты от кого-либо, использующего закрытие, и закрытия можно использовать повторно.
Public Shared Sub WrapFunc(ByVal f As Action)
_WrapFunc(f)
End Sub
Public Shared Sub WrapFunc(Of T1)(ByVal f As Action(Of T1), ByVal arg1 As T1)
_WrapFunc(Closure(f, arg1))
End Sub
Public Shared Sub WrapFunc(Of T1, T2)(ByVal f As Action(Of T1, T2), ByVal arg1 As T1, ByVal arg2 As T2)
_WrapFunc(Closure(f, arg1, arg2))
End Sub
Private Shared Sub _WrapFunc(ByVal f As Action)
' Test some stuff, start transaction
f()
' Test some stuff, end transaction
End Sub
Private Shared Function Closure(Of T1)(ByVal f As Action(Of T1), ByVal arg1 As T1) As Action
Return New Action(Function() _ActAsFunc(f, arg1))
End Function
Private Shared Function Closure(Of T1, T2)(ByVal f As Action(Of T1, T2), ByVal arg1 As T1, ByVal arg2 As T2) As Action
Return New Action(Function() _ActAsFunc(f, arg1, arg2))
End Function
Private Shared Function _ActAsFunc(Of T1)(ByVal f As Action(Of T1), ByVal arg1 As T1) As Object
f(arg1) : Return Nothing
End Function
Private Shared Function _ActAsFunc(Of T1, T2)(ByVal f As Action(Of T1, T2), ByVal arg1 As T1, ByVal arg2 As T2) As Object
f(arg1, arg2) : Return Nothing
End Function
Неполадка в том, что у меня голова вокруг закрытий на данный момент, но это, безусловно, выглядит очень перспективным! Я не против делать отдельные объявления функций, если они все одни лайнеры. Я определенно займусь этим дальше. – Zarigani
Получив прошлое мое первоначальное заблуждение, что «закрытие» было своего рода встроенным, я зашел в тупик при переводе «return() => action (p1)» на vb. Согласно документам «Visual Basic требует, чтобы выражение лямбда возвращало значение. В результате делегат Action не может использоваться с выражением лямбда в Visual Basic». Может ли это замыкание без этого? – Zarigani
Обнаружил путь вокруг него. Спасибо за вашу помощь. – Zarigani