当登录c#时,我如何才能知道调用当前方法的方法的名称?我知道所有关于System.Reflection.MethodBase.GetCurrentMethod(),但我想在堆栈跟踪中走一步。我考虑过解析堆栈跟踪,但我希望找到一种更清晰、更显式的方式,比如Assembly.GetCallingAssembly(),但用于方法。
当前回答
您可以使用Caller Information和可选参数:
public static string WhoseThere([CallerMemberName] string memberName = "")
{
return memberName;
}
这个测试说明了这一点:
[Test]
public void Should_get_name_of_calling_method()
{
var methodName = CachingHelpers.WhoseThere();
Assert.That(methodName, Is.EqualTo("Should_get_name_of_calling_method"));
}
虽然上面的StackTrace工作得相当快,在大多数情况下不会是一个性能问题,但调用者信息仍然要快得多。在1000次迭代的样本中,我发现它快了40倍。
其他回答
在c# 5中,你可以使用调用者信息来获取这些信息:
//using System.Runtime.CompilerServices;
public void SendError(string Message, [CallerMemberName] string callerName = "")
{
Console.WriteLine(callerName + "called me.");
}
也可以获取[CallerFilePath]和[CallerLineNumber]。
显然这是一个迟来的答案,但如果你能使用。net 4.5或更新版本,我有一个更好的选择:
internal static void WriteInformation<T>(string text, [CallerMemberName]string method = "")
{
Console.WriteLine(DateTime.Now.ToString() + " => " + typeof(T).FullName + "." + method + ": " + text);
}
这将打印当前的日期和时间,后面跟着“Namespace.ClassName”。并以“:text”结尾。 样例输出:
6/17/2016 12:41:49 PM => WpfApplication.MainWindow..ctor: MainWindow initialized
示例使用:
Logger.WriteInformation<MainWindow>("MainWindow initialized");
我们也可以用来找到调用者。
假设你有一个你定义的方法:
public void MethodA()
{
/*
* Method code here
*/
}
你想找到它的调用者。
1. 改变方法签名,这样我们就有了一个Action类型的参数(Func也可以):
public void MethodA(Action helperAction)
{
/*
* Method code here
*/
}
2. Lambda名称不是随机生成的。规则似乎是:> <CallerMethodName>__X 其中CallerMethodName被前面的函数替换,X是一个索引。
private MethodInfo GetCallingMethodInfo(string funcName)
{
return GetType().GetMethod(
funcName.Substring(1,
funcName.IndexOf(">", 1, StringComparison.Ordinal) - 1)
);
}
3.当我们调用MethodA时,Action/Func参数必须由调用方方法生成。 例子:
MethodA(() => {});
4. 在MethodA内部,我们现在可以调用上面定义的helper函数,并找到调用方方法的MethodInfo。
例子:
MethodInfo callingMethodInfo = GetCallingMethodInfo(serverCall.Method.Name);
通常,您可以使用System.Diagnostics. stacktrace类来获取System.Diagnostics。然后使用GetMethod()方法获取System.Reflection.MethodBase对象。然而,这种方法有一些注意事项:
它表示运行时堆栈——优化可以内联一个方法,并且您不会在堆栈跟踪中看到该方法。 它不会显示任何本机帧,所以即使有机会您的方法被本机方法调用,这也将不起作用,而且实际上目前没有可用的方法来做到这一点。
(注:我只是在扩展Firas Assad提供的答案。)
private static MethodBase GetCallingMethod()
{
return new StackFrame(2, false).GetMethod();
}
private static Type GetCallingType()
{
return new StackFrame(2, false).GetMethod().DeclaringType;
}
这里有一个很棒的课程:http://www.csharp411.com/c-get-calling-method/