代码之家  ›  专栏  ›  技术社区  ›  Zarigani

在dotnet中为具有任意数量参数的函数使用泛型?

  •  2
  • Zarigani  · 技术社区  · 15 年前

    我想要一个可以“包装”任何其他函数调用的函数。在这种特殊情况下,它允许我围绕某些特定操作编写一些更通用的事务处理。

    我可以为任何特定数量的参数编写此文件,例如,对于一个参数:

    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个参数、2个参数等有重复的代码。

    有办法吗?

    [编辑]感谢罗伯特·弗雷泽的C代码。以下是对vb的翻译:

    [Edit2]已更正代码。不幸的是,在vb中似乎没有办法使用单独的“actasfunc”函数。从好的方面来说,这些闭包对任何使用闭包的人都是隐藏的,并且闭包是可重用的。

    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
    
    3 回复  |  直到 15 年前
        1
  •  2
  •   Robert Fraser    15 年前

    不。我也希望有,我一直这样做。

    在内部,ms使用文本模板/代码生成工具生成重复代码。C中的一个选项是围绕参数创建闭包,然后将它们作为无参数System.Action传递给另一个函数;我不确定VB.NET是否支持这一点。

    下面是我在c中所做的,希望有vb.net经验的人能翻译一下:

    public void add(Action action, EventFlags flags) { addInternal(action, flags); }
    public void add<T1>(Action<T1> action, T1 p1, EventFlags flags) { addInternal(closure(action, p1), flags); }
    public void add<T1, T2>(Action<T1, T2> action, T1 p1, T2 p2, EventFlags flags) { addInternal(closure(action, p1, p2), flags); }
    public void add<T1, T2, T3>(Action<T1, T2, T3> action, T1 p1, T2 p2, T3 p3, EventFlags flags) { addInternal(closure(action, p1, p2, p3), flags); }
    public void add<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 p1, T2 p2, T3 p3, T4 p4, EventFlags flags) { addInternal(closure(action, p1, p2, p3, p4), flags); }
    
    private static Action closure<T1>(Action<T1> action, T1 p1) { return () => action(p1); }
    private static Action closure<T1, T2>(Action<T1, T2> action, T1 p1, T2 p2) { return () => action(p1, p2); }
    private static Action closure<T1, T2, T3>(Action<T1, T2, T3> action, T1 p1, T2 p2, T3 p3) { return () => action(p1, p2, p3); }
    private static Action closure<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action, T1 p1, T2 p2, T3 p3, T4 p4) { return () => action(p1, p2, p3, p4); }
    
        2
  •  0
  •   Benjamin Anderson    15 年前

    你不能用paramarray吗?

      Public Shared Sub WrapFunc(Of T)(ByVal f As Action(Of T), ByVal ParamArray args() As T)
            ' Test some stuff, start transaction
            For Each arg As T In args
                f(arg)
            Next
    
            ' Test some stuff, end transaction
        End Sub
    
        3
  •  0
  •   Steve Wortham    15 年前

    我没试过用泛型,但是 ParamArray ?

    Public Shared Sub WrapFunc(Of T)(ByVal f As Action(Of T()), ByVal ParamArray args() As T)
        ' Test some stuff, start transaction
        f(args)
        ' Test some stuff, end transaction
    End Sub