public class SomeClass
{
public void SomeMethod()
{
StackFrame frame = new StackFrame(1);
var method = frame.GetMethod();
var type = method.DeclaringType;
var name = method.Name;
}
}
现在假设您有另一个这样的课程:
public class Caller
{
public void Call()
{
SomeClass s = new SomeClass();
s.SomeMethod();
}
}
名称将是“呼叫”,类型将是“呼叫者”。
更新:两年后,我仍然对此表示赞同
在 .NET 4.5 中,现在有一种更简单的方法可以做到这一点。您可以利用
CallerMemberNameAttribute
。
继续前面的例子:
public class SomeClass
{
public void SomeMethod([CallerMemberName]string memberName = "")
{
Console.WriteLine(memberName); // Output will be the name of the calling method
}
}
您可以通过使用
StackTrace
来使用它,然后您可以从中获取反射类型。
StackTrace stackTrace = new StackTrace(); // get call stack
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
StackFrame callingFrame = stackFrames[1];
MethodInfo method = callingFrame.GetMethod();
Console.Write(method.Name);
Console.Write(method.DeclaringType.Name);
这实际上可以使用当前堆栈跟踪数据和反射的组合来完成。
public void MyMethod()
{
StackTrace stackTrace = new System.Diagnostics.StackTrace();
StackFrame frame = stackTrace.GetFrames()[1];
MethodInfo method = frame.GetMethod();
string methodName = method.Name;
Type methodsClass = method.DeclaringType;
}
1
数组上的StackFrame
索引将为您提供调用MyMethod
的方法
是的,原则上这是可能的,但它不是免费的。
您需要创建一个StackTrace,然后您可以查看调用堆栈的StackFrame。
从技术上讲,您可以使用 StackTrace,但这非常慢,并且很多时候不会给您期望的答案。这是因为在发布版本期间可能会发生优化,从而删除某些方法调用。因此,您无法在发布时确定堆栈跟踪是否“正确”。
确实,在 C# 中没有任何万无一失或快速的方法可以做到这一点。您真的应该问自己为什么需要这个以及如何构建您的应用程序,这样您就可以在不知道哪个方法调用它的情况下做您想做的事情。