就像标题说的:反射能给你当前正在执行的方法的名字吗?
我倾向于认为不是,因为海森堡的问题。如何调用一个方法,在不改变当前方法的情况下告诉您当前方法?但我希望有人能证明我错了。
更新:
第2部分:这也可以用于在代码中查找属性吗? 第三部分:演出是什么样的?
最终结果 我学习了MethodBase.GetCurrentMethod()。我还了解到,我不仅可以创建堆栈跟踪,还可以只创建我需要的确切帧。
要在属性中使用它,只需使用. substring(4)来删除'set_'或'get_'。
就像标题说的:反射能给你当前正在执行的方法的名字吗?
我倾向于认为不是,因为海森堡的问题。如何调用一个方法,在不改变当前方法的情况下告诉您当前方法?但我希望有人能证明我错了。
更新:
第2部分:这也可以用于在代码中查找属性吗? 第三部分:演出是什么样的?
最终结果 我学习了MethodBase.GetCurrentMethod()。我还了解到,我不仅可以创建堆栈跟踪,还可以只创建我需要的确切帧。
要在属性中使用它,只需使用. substring(4)来删除'set_'或'get_'。
当前回答
我认为你应该能够从创建一个StackTrace。或者,正如@edg和@Lars Mæhlum提到的,MethodBase.GetCurrentMethod()
其他回答
这个怎么样:
StackFrame frame = new StackFrame(1);
frame.GetMethod().Name; //Gets the current method name
MethodBase method = frame.GetMethod();
method.DeclaringType.Name //Gets the current class name
在空控制台程序的Main方法中试试这个:
MethodBase method = MethodBase.GetCurrentMethod();
Console.WriteLine(method.Name);
控制台输出: 主要
简单的处理方法是:
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name;
如果系统。反射包含在using块中:
MethodBase.GetCurrentMethod().DeclaringType.FullName + "." + MethodBase.GetCurrentMethod().Name;
Lex提供的片段有点长,所以我指出了重要的部分,因为没有其他人使用完全相同的技术:
string MethodName = new StackFrame(0).GetMethod().Name;
这将向MethodBase.GetCurrentMethod()返回相同的结果。命名技巧,但它仍然值得指出,因为我可以在它自己的方法中实现一次,使用前一个方法的索引1,并从许多不同的属性调用它。此外,它只返回一帧而不是整个堆栈跟踪:
private string GetPropertyName()
{ //.SubString(4) strips the property prefix (get|set) from the name
return new StackFrame(1).GetMethod().Name.Substring(4);
}
这也是一行代码;)
比较获得方法名的方法——在LinqPad中使用任意计时结构:
CODE
void Main()
{
// from http://blogs.msdn.com/b/webdevelopertips/archive/2009/06/23/tip-83-did-you-know-you-can-get-the-name-of-the-calling-method-from-the-stack-using-reflection.aspx
// and https://stackoverflow.com/questions/2652460/c-sharp-how-to-get-the-name-of-the-current-method-from-code
var fn = new methods();
fn.reflection().Dump("reflection");
fn.stacktrace().Dump("stacktrace");
fn.inlineconstant().Dump("inlineconstant");
fn.constant().Dump("constant");
fn.expr().Dump("expr");
fn.exprmember().Dump("exprmember");
fn.callermember().Dump("callermember");
new Perf {
{ "reflection", n => fn.reflection() },
{ "stacktrace", n => fn.stacktrace() },
{ "inlineconstant", n => fn.inlineconstant() },
{ "constant", n => fn.constant() },
{ "expr", n => fn.expr() },
{ "exprmember", n => fn.exprmember() },
{ "callermember", n => fn.callermember() },
}.Vs("Method name retrieval");
}
// Define other methods and classes here
class methods {
public string reflection() {
return System.Reflection.MethodBase.GetCurrentMethod().Name;
}
public string stacktrace() {
return new StackTrace().GetFrame(0).GetMethod().Name;
}
public string inlineconstant() {
return "inlineconstant";
}
const string CONSTANT_NAME = "constant";
public string constant() {
return CONSTANT_NAME;
}
public string expr() {
Expression<Func<methods, string>> ex = e => e.expr();
return ex.ToString();
}
public string exprmember() {
return expressionName<methods,string>(e => e.exprmember);
}
protected string expressionName<T,P>(Expression<Func<T,Func<P>>> action) {
// https://stackoverflow.com/a/9015598/1037948
return ((((action.Body as UnaryExpression).Operand as MethodCallExpression).Object as ConstantExpression).Value as MethodInfo).Name;
}
public string callermember([CallerMemberName]string name = null) {
return name;
}
}
结果
反射 反射
堆栈跟踪 堆栈跟踪
inlineconstant inlineconstant
常数 常数
埃克普尔 e => e.expr()
exprmember exprmember
callermember 主要
Method name retrieval: (reflection) vs (stacktrace) vs (inlineconstant) vs (constant) vs (expr) vs (exprmember) vs (callermember)
154673 ticks elapsed ( 15.4673 ms) - reflection
2588601 ticks elapsed (258.8601 ms) - stacktrace
1985 ticks elapsed ( 0.1985 ms) - inlineconstant
1385 ticks elapsed ( 0.1385 ms) - constant
1366706 ticks elapsed (136.6706 ms) - expr
775160 ticks elapsed ( 77.516 ms) - exprmember
2073 ticks elapsed ( 0.2073 ms) - callermember
>> winner: constant
注意expr和callermember方法并不完全“正确”。在这里,您可以看到一个重复的相关评论,即反射比stacktrace快15倍。