.net 获取通过lambda表达式传递的方法名称?
是否可以通过反射检索通过lambda表达式传递的真实方法名 我希望通过更好的错误处理来平台调用一些函数,然后为了避免重复大量的.net 获取通过lambda表达式传递的方法名称?,.net,vb.net,reflection,delegates,pinvoke,.net,Vb.net,Reflection,Delegates,Pinvoke,是否可以通过反射检索通过lambda表达式传递的真实方法名 我希望通过更好的错误处理来平台调用一些函数,然后为了避免重复大量的封送处理.GetLastWin32Error条件,我在创建一个通用方法来自动化它,在这里我传递一个引用对象和一个lambda表达式: <DebuggerStepThrough> Private Shared Sub SafePInvoke(Of T)(ByRef resultVar As T, ByVal [function] As Func(Of T))
封送处理.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
我不知道它是否能改进得更多,知道它会很好
好吧,现在,为了美观起见,如果函数出现win32错误,我会抛出一个异常,在异常消息中我想显示真实的方法名,在本例中是GetWindowTextLength
,而不是“匿名”lambda名
这可能是?我不会这么做。传递表示要显示的错误消息或其中一部分(如函数名)的字符串变量会更简单 “最简单”的方法是使用一个。为此,您需要更改
SafePInvoke
的签名以接受表达式
这样,您就可以编译表达式,并调用它来执行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
导入System.Linq.Expressions
...
私有共享子安全密码voke(Of T)(ByRef result作为T,expr作为表达式(Of Func(Of T)))
'编译函数并调用它
Dim result=expr.Compile.Invoke()
Dim lastError为整数=Marshal.GetLastWin32Error
如果最后一个错误为0,则
'这很简单,但它是带有参数的完整签名
'Dim name=expr.Body.ToString
'ToDo:添加try Catch
Dim MethName=CType(expr.Body,MethodCallExpression).Method.Name
Dim errMsg=MethName&“失败”
如果结束
端接头
铸造它以获得名称是Sehnsucht的想法,我暂时放弃了。你可能不喜欢结果,你可以求助于表达式树。但是,主体将是GetWindowTextLength(hWnd)
您可能不需要参数。从表达式主体,我认为可以将其强制转换为MethodCallExpression
,并获取其方法
属性(类型为MethodInfo,具有Name属性)。使用表达式也意味着您必须在方法中编译它才能调用它。如果我们讨论的是获取参数的语法,那么实际上我不喜欢我必须编写的当前语法(lambda表达式语法的“Function()”关键字)。表达式树将增加和/或使参数?中的写入量变得复杂,我第一次听说表达式树(我已经在MSDN中查找)它并没有那么坏:Sub-SafePInvoke(of T)(ByRef resultVar As T,expr As expression(of Func(of T))
但这不是你第二次要求的“无法完成此部分”;您想要一个名称,只需请求一个(可能比实际方法名称更清晰)。此外,通过添加VB14,您将拥有NameOf
运算符,可以减少“神奇字符串效应”:SafePInvoke(length,Function()NativeMethods.GetWindowTextLength(hWnd),NameOf(NativeMethods.GetWindowTextLength))
确定是“重复代码”“但至少重命名可以与that@Plutonix再次感谢,你能解释一下你为什么不这么做吗?这仅仅是因为对于美学方面的东西,你会先传递一个字符串,或者是因为在使用表达式时,性能有问题吗?它很复杂,我不喜欢expr->lambda->Pinvoke的想法;对我来说太间接了。@ElektroStudios,给他一个关于给他分数和一个铜牌(完成)的投票,也许现在用MethodCallExpression
对象我能做点什么吗?请看一下,我正在分析整个类MethodCallExpression
,特别是属性属性,但是它有很多属性和成员来了解它的用途。
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