就像标题说的:反射能给你当前正在执行的方法的名字吗?

我倾向于认为不是,因为海森堡的问题。如何调用一个方法,在不改变当前方法的情况下告诉您当前方法?但我希望有人能证明我错了。

更新:

第2部分:这也可以用于在代码中查找属性吗? 第三部分:演出是什么样的?

最终结果 我学习了MethodBase.GetCurrentMethod()。我还了解到,我不仅可以创建堆栈跟踪,还可以只创建我需要的确切帧。

要在属性中使用它,只需使用. substring(4)来删除'set_'或'get_'。


当前回答

试试这个…

    /// <summary>
    /// Return the full name of method
    /// </summary>
    /// <param name="obj">Class that calls this method (use Report(this))</param>
    /// <returns></returns>
    public string Report(object obj)
    {
        var reflectedType = new StackTrace().GetFrame(1).GetMethod().ReflectedType;
        if (reflectedType == null) return null;

        var i = reflectedType.FullName;
        var ii = new StackTrace().GetFrame(1).GetMethod().Name;

        return string.Concat(i, ".", ii);
    }

其他回答

在空控制台程序的Main方法中试试这个:

MethodBase method = MethodBase.GetCurrentMethod();
Console.WriteLine(method.Name);

控制台输出: 主要

using System;
                    
public class Program
{
    public static void Main()
    {
        
        Console.WriteLine("1: {0} {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, System.Reflection.MethodBase.GetCurrentMethod().ReflectedType);
        OtherMethod();
    }
    
    public static void OtherMethod()
    {
        Console.WriteLine("2: {0} {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, System.Reflection.MethodBase.GetCurrentMethod().ReflectedType);
    }
}

输出:

1: Main Program
2: OtherMethod Program

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);
}

这也是一行代码;)

对于异步方法,你可以使用:

//using System.Reflection;

var myMethodName = MethodBase
                    .GetCurrentMethod()
                    .DeclaringType
                    .Name
                    .Substring(1)
                    .Split('>')[0];

从。net 4.5开始,你也可以使用[CallerMemberName]。

示例:一个属性setter(回答第2部分):

protected void SetProperty<T>(T value, [CallerMemberName] string property = null)
{
    this.propertyValues[property] = value;
    OnPropertyChanged(property);
}

public string SomeProperty
{
    set { SetProperty(value); }
}

编译器将在调用点提供匹配的字符串字面量,因此基本上没有性能开销。