我有一个函数可以调用我的一个套接字类型。如果有错误,我希望能够打印警告并重试。在警告中,我想要方法名称。然而,它被宣布为lambda。这甚至可能吗?
我如何调用函数(假设函数名为myMain):
SafeSocketCommand(() => this.mySocket.ReadCurrentBuffer());
基本包装功能:
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;
}
但是socketCommand.Method.Name给了我调用方法(来自Stack Trace?)'&lt; myMain&gt; b__3'我希望socketCommand(mySocket.ReadCurrentBuffer)调用实际函数。是否有可能在任何地方获取此信息,或者由于在lambda中声明而丢失?
编辑:
我应该提到我使用这个特殊的调用约定,以便我可以使用各种签名的基于套接字的命令。
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))
它还通过重载处理没有返回类型的签名:
protected void SafeSocketCommand(Action socketCommand)
{
SafeSocketCommand(() => { socketCommand(); return 0; });
}
答案 0 :(得分:5)
如果您修改SafeSocketCommand
以接受Expression<Func<TResult>>
,那么您将可以访问表示lambda正文的表达式树,您可以从中访问ReadCurrentBuffer
调用直接
但是,如果你这样做,你将不再处理常规的匿名方法;要实际调用它,您需要将表达式树编译为代码。您可能还需要灵活处理代码期望在lambda体内出现的内容。
答案 1 :(得分:2)
不,因为lambda没有名字;他们是匿名的功能。但是,您可以从最后一个堆栈框架中获取方法名称:
new StackFrame(1).GetMethod().Name;
答案 2 :(得分:2)
Func<TResult>
只是一名代表。而不是使用lambda,创建一个匹配Func<TResult>
的签名并调用它的方法。这样,你就可以得到你想要的任何名字。
SafeSocketCommand(MyNewMethod);
...
public TResult MyNewMethod()
{
return this.mySocket.ReadCurrentBuffer();
}
答案 3 :(得分:0)
在这种情况下,您可以简单地调用此调用。它也会更快,更小的生成代码。
SafeSocketCommand(mySocket.ReadCurrentBuffer);
通常,Exception对象的StackTrace包含您要查找的完整信息,很多比打印方法名称更准确,或者您可以使用{{3} }属性,用于抛出异常的方法的名称。