I have a function that wraps a call to one of my socket types. If there is an error, I want to be able to print a warning and retry. In the warning, I want to have the method name. However, it was declared as a lambda. Is this even possible?
How I call the function (assume in function called myMain):
SafeSocketCommand(() => this.mySocket.ReadCurrentBuffer());
Basic wrapping function:
protected TResult SafeSocketCommand<TResult>(Func<TResult> socketCommand)
{
TResult retValue = default(TResult);
try
{
retValue = socketCommand();
}
catch (PacketLost)
{
ReportToLogs("Timeout on command '" + socketCommand.Method.Name);
}
return retValue;
}
But socketCommand.Method.Name gives me the calling method (from the Stack Trace?) ‘< myMain >b__3’ and I want the actual function being invoked by socketCommand (mySocket.ReadCurrentBuffer). Is it possible to get this information anywhere, or is it lost due to declaring in a lambda?
EDIT:
I should have mentioned that I use this particular calling convention so that I can use socket based commands of various signatures.
int i = SafeSocketCommand(() => this.mySocket.FunctionReturnsInt())
bool b = SafeSocketCommand(() => this.mySocket.FunctionReturnsBool(string s))
object o = SafeSocketCommand(() => this.mySocket.Complicated(string s, int i, bool b))
It also handles no return type signatures by overloading:
protected void SafeSocketCommand(Action socketCommand)
{
SafeSocketCommand(() => { socketCommand(); return 0; });
}
If you modify your
SafeSocketCommandto accept anExpression<Func<TResult>>then you’ll get access to an expression tree that represents the body of the lambda, from which you can access theReadCurrentBuffercall directly.However, if you do this, you’re no longer dealing with a regular anonymous method; to actually call it you’ll need to compile the expression tree to code. You may also need to be flexible as to what your code expects to appear inside the lambda’s body.