C# 获取上次调用的方法的名称

C# 获取上次调用的方法的名称,c#,c#-4.0,methods,C#,C# 4.0,Methods,我有以下代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); try { this.CheckValue(true); // call method } catch(Exception ex) { // how to get here

我有以下代码:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        try
        {
            this.CheckValue(true); // call method
        }
        catch(Exception ex)
        {
            // how to get here name of last called method
        }
    }

    public int CheckValue(bool sender)
    {
        var qwe = int.Parse("qwe"); // invoke an exception

        return 0;
    }
}
我需要输入最后一个被调用方法的“catch block”名称(在本例中为“CheckValue”),但它返回被调用的方法是“StringToNumber”

我尝试使用StackTrace获取它:

stackTrace.GetFrame(1).GetMethod().Name; -> "Main"
MethodBase.GetCurrentMethod(); -> "Void .ctor()"
ex.TargetSite.Name; -> "StringToNumber"

有可能这样做吗?

我不知道你为什么要这样做。。因为这是预期的行为。异常的位置就是您正在显示的位置。。在int.Parse()调用中

尽管如此。。如果你真的想这么做,你需要尝试一下。。捕获CheckValue,然后从那里重新抛出异常,但方式会破坏调用堆栈。。像这样:

public int CheckValue(bool sender) {
    try {
        var qwe = int.Parse("qwe"); // invoke an exception

        return 0;
    }
    catch (Exception ex) {
        throw ex; // this breaks the call stack and re-throws the exception from here..
    }
}

然后,ex.TargetSite.Name==“CheckValue”。我还是不知道你为什么要这么做。。因为堆栈跟踪实际上会向您显示失败后所有堆栈的展开位置。

我不知道您为什么要这样做。。因为这是预期的行为。异常的位置就是您正在显示的位置。。在int.Parse()调用中

尽管如此。。如果你真的想这么做,你需要尝试一下。。捕获CheckValue,然后从那里重新抛出异常,但方式会破坏调用堆栈。。像这样:

public int CheckValue(bool sender) {
    try {
        var qwe = int.Parse("qwe"); // invoke an exception

        return 0;
    }
    catch (Exception ex) {
        throw ex; // this breaks the call stack and re-throws the exception from here..
    }
}
然后,ex.TargetSite.Name==“CheckValue”。我还是不知道你为什么要这么做。。作为堆栈跟踪,它将实际显示故障后所有堆栈的展开位置。

简短回答:

你不能。
长答覆:

如果确实需要这样做,则需要在所有要跟踪的方法中执行日志代码

您可以创建一个全局变量(ugh)来存储上次调用的方法的
MethodInfo
,并在每个方法中,将其设置为
MethodBase.GetCurrentMethod()
。然后,只要您愿意,就可以检查该变量,看看哪个方法最后设置它


在您的例子中,您可能正在尝试确定抛出异常的方法。您看到的是
TargetSite
,它返回层次结构中最低的方法,而您似乎想要的是当前方法正下方的方法。如果仅仅检查
Exception.StackTrace
并不能提供足够的信息,您可能能够从
StackTrace
中解析出信息,并使用反射来获取
MethodInfo
。通常,
StackTrace
就足够了

您还可以在顶级方法中抛出新异常,以便从新异常中获取
TargetSite

总结:

如果
Exception.StackTrace
没有提供足够的信息,则您必须:

  • 在要检查的每个方法中执行日志代码
  • 解析出可以从
    异常中获得的信息
  • 更改异常引发方案以引发新异常,并将
    InnerException
    设置为原始异常
简短回答:

你不能。
长答覆:

如果确实需要这样做,则需要在所有要跟踪的方法中执行日志代码

您可以创建一个全局变量(ugh)来存储上次调用的方法的
MethodInfo
,并在每个方法中,将其设置为
MethodBase.GetCurrentMethod()
。然后,只要您愿意,就可以检查该变量,看看哪个方法最后设置它


在您的例子中,您可能正在尝试确定抛出异常的方法。您看到的是
TargetSite
,它返回层次结构中最低的方法,而您似乎想要的是当前方法正下方的方法。如果仅仅检查
Exception.StackTrace
并不能提供足够的信息,您可能能够从
StackTrace
中解析出信息,并使用反射来获取
MethodInfo
。通常,
StackTrace
就足够了

您还可以在顶级方法中抛出新异常,以便从新异常中获取
TargetSite

总结:

如果
Exception.StackTrace
没有提供足够的信息,则您必须:

  • 在要检查的每个方法中执行日志代码
  • 解析出可以从
    异常中获得的信息
  • 更改异常引发方案以引发新异常,并将
    InnerException
    设置为原始异常
简短回答:

是的,你可以


我只是在玩扩展方法,这里的技巧是获取所需类的最后一帧,否则它将获取mscorlib assembly的方法。那么就这样吧:

public static string GetLastCalledMethod<T>(this Exception ex)
{
    var stackTrace = new System.Diagnostics.StackTrace(ex);
    var lastFrame = stackTrace.GetFrames().FirstOrDefault(frame => frame.GetMethod().DeclaringType.FullName == typeof(T).FullName);

    string methodName = string.Empty;
    if (lastFrame != null)
        methodName = lastFrame.GetMethod().Name;

    return methodName;
}
公共静态字符串GetLastCalledMethod(此异常为ex)
{
var stackTrace=新系统.Diagnostics.stackTrace(ex);
var lastFrame=stackTrace.GetFrames().FirstOrDefault(frame=>frame.GetMethod().DeclaringType.FullName==typeof(T.FullName);
string methodName=string.Empty;
if(lastFrame!=null)
methodName=lastFrame.GetMethod().Name;
返回方法名;
}
简短回答:

是的,你可以


我只是在玩扩展方法,这里的技巧是获取所需类的最后一帧,否则它将获取mscorlib assembly的方法。那么就这样吧:

public static string GetLastCalledMethod<T>(this Exception ex)
{
    var stackTrace = new System.Diagnostics.StackTrace(ex);
    var lastFrame = stackTrace.GetFrames().FirstOrDefault(frame => frame.GetMethod().DeclaringType.FullName == typeof(T).FullName);

    string methodName = string.Empty;
    if (lastFrame != null)
        methodName = lastFrame.GetMethod().Name;

    return methodName;
}
公共静态字符串GetLastCalledMethod(此异常为ex)
{
var stackTrace=新系统.Diagnostics.stackTrace(ex);
var lastFrame=stackTrace.GetFrames().FirstOrDefault(frame=>frame.GetMethod().DeclaringType.FullName==typeof(T.FullName);
string methodName=string.Empty;
if(lastFrame!=null)
methodName=lastFrame.GetMethod().Name;
返回方法名;
}

为了吸引更多的答案,您应该添加一个与您使用的语言或工具相对应的标签。你可以通过在编辑页面的底部添加标签来实现这一点。你还可以告诉我们你为什么要这么做的背景吗?通过