2010-04-21 42 views
2

我想有一個函數可以「包裝」任何其他函數調用。在這種特殊情況下,它將允許我圍繞某些特定操作編寫一些更通用的事務處理。在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對阿根廷,2個ARGS等

有一個這樣做的方式?

[編輯]感謝羅伯特·弗雷澤的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 

回答

2

沒有。我也希望有,我一直這樣做。

內部,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); } 
+0

在困擾我暫時關閉關閉時遇到困難,但這看起來非常有希望!如果它們都是一行,我不介意做單獨的函數聲明。我一定會進一步研究這一點。 – Zarigani 2010-04-21 22:23:08

+0

經過我最初的誤解,認爲「閉包」是某種內置的,我在將「return()=> action(p1)」翻譯成vb時遇到了一個死衚衕。根據文檔,「Visual Basic要求lambda表達式返回一個值,因此,Action委託不能與Visual Basic中的lambda表達式一起使用。」 沒有這封閉措辭可以措辭? – Zarigani 2010-04-21 23:12:39

+0

找到了解決辦法。謝謝你的幫助。 – Zarigani 2010-04-21 23:47:18

0

我還沒有泛型試過,但對於一個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 
+0

在這種情況下,行「f(args)」是編譯錯誤。 f是一個Action(Of T),而不是一個Action(Of LotsOfT)。 – Zarigani 2010-04-21 21:53:13

+0

@Zarigani - 啊,好的。那麼如果你使用Action(Of T())呢?這不行嗎? (我剛剛更新的代碼) – 2010-04-21 21:59:35

+0

是,行動(中T())的作品,但只有當他的所有參數總是將是相同類型和所有行動接受陣列(或ParamArray參數)作爲參數。儘管我知道盡管沒有辦法做可變數量的類型。 – adam0101 2010-04-21 22:08:10

0

你不能使用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 
+0

這將使用不同的參數反覆調用相同的函數。不是像OP想要的那樣的多參數功能。 – 2010-04-21 22:02:40