【发布时间】:2015-06-16 20:57:32
【问题描述】:
是否可以通过 Reflection 检索通过 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 而不是“匿名" lambda 名称。
这可能吗?
【问题讨论】:
-
你可能不喜欢这个结果,你可以求助于表达式树。然而,身体将是
GetWindowTextLength(hWnd)你可能不想要参数。 -
从表达式主体我认为可以将其转换为
MethodCallExpression并将其作为Method属性(具有 Name 属性的 MethodInfo 类型)。使用表达式还意味着您必须在方法中编译它才能调用它。 -
如果对于结果,我们正在谈论接受参数的语法,那么实际上我不喜欢我必须编写的当前语法(lambda 表达式语法的“Function()”关键字)。表达式树会增加和/或会使参数中的写入量变得复杂?我第一次听说表达式树(我已经在 MSDN 中查找了)
-
它不是*那*糟糕:
Sub SafePInvoke(Of T)(ByRef resultVar As T, expr As Expression(Of Func(Of T)))但这不是你想要的
标签: .net vb.net reflection delegates pinvoke