获取通过 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的主意,我暂时放弃了。
是否可以通过 反射 检索通过 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的主意,我暂时放弃了。