如何在C#中获取调用方法
如何在C#中获取调用方法
可能是重复问题:
我需要一种方法来知道在C#中调用方法的名称。
例如:
private void doSomething() { // 我需要知道是谁在调用我?(是方法1还是方法2)。 // 根据调用你的人来做一些事情? } private void method1() { doSomething(); } private void method2() { doSomething(); }
问题的出现原因:
问题的提问者想要获取调用方法的名称,但是其他回答者认为这样做是不合适的。调用方法不应该知道谁在调用它,而应该将调用方法的不同之处抽象成参数,并传递给被调用的方法。
解决方法:
将调用方法的不同之处抽象成参数,并传递给被调用的方法。这样,如果添加了一个新的调用方法,被调用的方法可以根据传递的参数来执行不同的操作。
以下是一个示例代码:
private void doSomething(bool doItThisWay) { if (doItThisWay) { // Do it one way } else { // Do it the other way } } private void method1() { doSomething(true); } private void method2() { doSomething(false); }
这样,如果需要添加一个method3方法,它可以根据传递的参数来执行不同的操作,而被调用的方法不需要关心调用它的方法是什么。
如果只是为了输出调试信息,可以考虑将方法名作为参数传递给被调用的方法。但是除了调试之外,这种做法并不是一个好主意。
以上是其他回答者对于问题的原因和解决方法的讨论。其中有人认为这种做法不是一个正确的答案,因为调用方法并不能直接获取到方法名。
在C#中获取调用方法的名称有多种方法,其中一种是使用反射来获取。下面的代码展示了如何使用StackTrace类来获取调用方法的名称:
using System.Diagnostics; // 获取调用堆栈 StackTrace stackTrace = new StackTrace(); // 获取调用方法的名称 Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
然而,在发布版本中,由于即时编译器(JIT compiler)可以对代码进行优化,所以不能依赖这种方法获取方法的名称。因此,我们需要采取其他方法来获取先前调用的方法。通过改变GetFrame()方法的参数,我们可以获取调用堆栈中所有的方法。在这种情况下,使用(1)作为参数可以获取调用堆栈中的上一个方法。
然而,需要注意的是,为了确保方法不被内联(inlined),我们需要在方法上添加[MethodImpl(MethodImplOptions.NoInlining)]特性。
虽然使用堆栈跟踪(stack trace)可以方便地获取调用方法的信息,但是在非调试或日志记录的情况下,应该避免使用堆栈跟踪,因为它会导致性能下降。
对于一些人来说,使用堆栈跟踪可以作为快速调试助手,帮助他们了解是哪些方法调用了特定的方法。
有人说使用堆栈跟踪会影响性能,这是真的吗?性能可能会受到一些影响,但在我个人的案例中(最多连续调用150次),我甚至无法测量到差异。但是,我非常强调Stormenet/Hans Passant所说的,不要在发布版本中依赖这种方法。我曾经花了两天时间来寻找一个bug,最后发现是由于这个问题造成的。这个问题非常难以理解,因为你可以添加一些无意义的代码来阻止内联,并且你的代码在调试模式下可以正常工作。