喜欢的标题说:可以反射给你的名字当前正在执行的方法。

我倾向于想不会,因为海森堡的问题。你怎么称呼一个方法,该方法将会告诉你目前的方法,而不改变目前的方法是什么?但我希望有人可以证明我是错误的。

更新:

  • 第2部分:这可能是用来看看里面的代码一个酒店?
  • 第3部分:会是什么样的表现是怎样的?

最终的结果
我学会了关于该.GetCurrentMethod().我还了解到,不仅可以创建一个堆栈,我只能创建的确切框架,我需要如果我想要的。

使用这一内部财产,只是采取一个。Substring(4)删除'set_'或'get_'.

有帮助吗?

解决方案

为。净额4.5你也可以使用 [CallerMemberName]

例如:一个酒店器(回答第2部分):

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

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

编译器将提供匹配的字符串在的状态位通过下面的命令,因此存在基本上没有效能的开销。

其他提示

该段提供的Lex是有点长,所以我要指出的重要一部分由于没有其他人使用了完全相同的技术:

string MethodName = new StackFrame(0).GetMethod().Name;

这应该返回相同的结果 该.GetCurrentMethod().名称 技术,但它仍然值得指出的因为我可能实现这一次是在其自己的方法,使用指标1的 以前的 方法,并呼吁它从一些不同的性质。此外,它只是返回的一个框架,而不是整个堆栈跟踪:

private string GetPropertyName()
{  //.SubString(4) strips the property prefix (get|set) from the name
    return new StackFrame(1).GetMethod().Name.Substring(4);
}

这是一个衬垫,也;)

试试这里的主要方法中的一个空的控制台节目:

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

控制台输出:
Main

是的肯定。

如果你想的一个目的操纵事实上我使用一个功能是这样的:

public static T CreateWrapper<T>(Exception innerException, params object[] parameterValues) where T : Exception, new()
{
    if (parameterValues == null)
    {
        parameterValues = new object[0];
    }

    Exception exception   = null;
    StringBuilder builder = new StringBuilder();
    MethodBase method     = new StackFrame(2).GetMethod();
    ParameterInfo[] parameters = method.GetParameters();
    builder.AppendFormat(CultureInfo.InvariantCulture, ExceptionFormat, new object[] { method.DeclaringType.Name, method.Name });
    if ((parameters.Length > 0) || (parameterValues.Length > 0))
    {
        builder.Append(GetParameterList(parameters, parameterValues));
    }

    exception = (Exception)Activator.CreateInstance(typeof(T), new object[] { builder.ToString(), innerException });
    return (T)exception;
}

这一行:

MethodBase method     = new StackFrame(2).GetMethod();

走这堆框架找到的调用的方法那么我们使用反映获得的参数值的信息传递给它的一般错误的报告功能。获得当前的方法只是使用目前的堆框架(1)替代。

正如其他人所说的目前的方法名称你还可以使用:

MethodBase.GetCurrentMethod()

我喜欢走路叠,因为如果看起来内部在那方法很简单的创建了一个StackCrawlMark无论如何。处理这堆直接似乎更加清晰对我

后4.5你现在可以使用[CallerMemberNameAttribute]的一部分方法参数,以获得一串的方法的名字-这可能有助于在某些情况下(但真的在说上述示例)

public void Foo ([CallerMemberName] string methodName = null)

这似乎主要是一个解决方案,举支持在哪里之前你已经串充满了所有通过你的事件代码。

比较的方法来获得方法的名称--使用的一个 任意时间构造 在LinqPad:

代码

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

expr 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

注意, exprcallermember 方法并不是非常"正确的"。还有你看到一个重复的 一个相关的评论 这反映是-15倍的速度比堆栈跟踪.

编辑:该可能是一个更好的办法只得到的方法是在(而不是整个叫stack)。我还会关心的内联然而。

你可以使用一个堆栈跟踪内法:

StackTrace st = new StackTrace(true);

和看起来的框架:

// The first frame will be the method you want (However, see caution below)
st.GetFrames();

但是,要知道,如果方法的内联的,你不会进去的方法你以为你是。你可以使用的一个属性,以防止内联:

[MethodImpl(MethodImplOptions.NoInlining)]

简单的方法来处理是:

System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name;

如果系统。反思包括在使用块:

MethodBase.GetCurrentMethod().DeclaringType.FullName + "." + MethodBase.GetCurrentMethod().Name;

这个怎么样:

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

我认为你应该能够获得,从创建一个 堆栈跟踪.或者,如@电子讨论组 和@拉尔斯Mæhlum 提到,该.GetCurrentMethod()

如果你需要的仅仅是串名字的方法,可以使用的表达。看看 http://joelabrahamsson.com/entry/getting-property-and-method-names-using-static-reflection-in-c-sharp

试试这个...

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

我只是做这有一个简单的静态级:

using System.Runtime.CompilerServices;
.
.
.
    public static class MyMethodName
        {
            public static string Show([CallerMemberName] string name = "")
            {
                return name;
            }
        }

然后在你的代码:

private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text = MyMethodName.Show();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            textBox1.Text = MyMethodName.Show();
        }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top