Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 获取通过lambda表达式传递的方法名称?_.net_Vb.net_Reflection_Delegates_Pinvoke - Fatal编程技术网

.net 获取通过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))

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

我希望通过更好的错误处理来平台调用一些函数,然后为了避免重复大量的
封送处理.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