获取通过 lambda 表达式传递的方法名称?

Get the method name that was passed through a lambda expression?

是否可以通过 反射 检索通过 lambda 表达式传递的真实方法名称?

我想通过更好的错误处理平台调用一些函数,然后为了避免重复大量的 Marshal.GetLastWin32Error 条件,我想创建一个通用方法来自动化它,我传递一个引用对象和一个 lambda 表达式:

<DebuggerStepThrough>
Private Shared Sub SafePInvoke(Of T)(ByRef resultVar As T, ByVal [function] As Func(Of T))

    resultVar = [function].Invoke

    Dim lastError As Integer = Marshal.GetLastWin32Error

    If lastError <> 0 Then
        Throw New Win32Exception([error]:=lastError, message:=String.Format("Function '{0}' thrown an unhandled Win32 exception with error code '{1}'.",
                                                                            [function].Method.Name, CStr(lastError)))
    End If

End Sub

然后,我可以这样做来简化错误处理:

Dim length As Integer
SafePInvoke(length, Function() NativeMethods.GetWindowTextLength(hWnd))

不知道能不能再改进,知道就好了

好吧,现在,为了美观,如果函数遇到 win32 错误,我会抛出异常,在异常消息中我想显示真实的方法名称,在本例中为 GetWindowTextLength "anonymous" lambda 名称。

这可能是?

我不会这样做。传递一个表示您要显示的错误消息或其一部分(如函数名称)的字符串 var 会更简单。

"simplest" 方法是使用 Expression Tree。为此,您需要更改 SafePInvoke 的签名以接受 Expression

这样您就可以编译表达式,并调用它来执行 PInvoke。如果有错误,对表达式树进行运算得到名称:

Imports System.Linq.Expressions
...
Private Shared Sub SafePInvoke(Of T)(ByRef result As T, expr As Expression(Of Func(Of T)))
    ' compile the function and invoke it
    Dim result = expr.Compile.Invoke()

    Dim lastError As Integer = Marshal.GetLastWin32Error

    If lastError <> 0 Then
        ' this is easy, but it is the full signature w/ params
        'Dim name = expr.Body.ToString

        ' ToDo: add try Catch
        Dim MethName = CType(expr.Body, MethodCallExpression).Method.Name

        Dim errMsg = MethName & " failed"
    End If
End Sub

取名是Sehnsucht的主意,我暂时放弃了。