Is it possible to retrieve via Reflection the real method name that was passed through a lambda expression?
I would like to platform invoke some functions with a better error-handling, then to avoid repeating tons of Marshal.GetLastWin32Error
conditionals, I thinked in create a generic method to automate that, where I pass a reference object and a lambda expression:
<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
Then, I can do this to simplify error-handlings:
Dim length As Integer
SafePInvoke(length, Function() NativeMethods.GetWindowTextLength(hWnd))
I don't know if it can be improved more, it would be great to know it.
Well, now, and just for aesthetical things, If the function gets a win32 error I throw an exception and in the exception message I would like to show the real method name, in this case GetWindowTextLength
instead of the "anonymous" lambda name.
This is possibly?.
I would not do this. It would be simpler to pass a string var representing the error message you want to display or a portion thereof (like the function name).
The "simplest" way would be to use an Expression Tree. For this, you would need to change the signature of
SafePInvoke
to accept anExpression
.With that you could compile the expression, and invoke it to execute the PInvoke. If there is an error, work the expression tree to get the name:
Casting it to get the name was Sehnsucht's idea, I gave up for the time being.