How to get method name from Action in WinRT

2019-06-08 19:27发布

I'm trying to get the method name from an Action in WinRT, where Action.Method is not available. So far I have this:

public class Test2
{
    public static Action<int> TestDelegate { get; set; }

    private static string GetMethodName(Expression<Action<int>> e)
    {
        Debug.WriteLine("e.Body.NodeType is {0}", e.Body.NodeType);
        MethodCallExpression mce = e.Body as MethodCallExpression;
        if (mce != null)
        {
            return mce.Method.Name;
        }
        return "ERROR";
    }

    public static void PrintInt(int x)
    {
        Debug.WriteLine("int {0}", x);
    }

    public static void TestGetMethodName()
    {
        TestDelegate = PrintInt;
        Debug.WriteLine("PrintInt method name is {0}", GetMethodName(x => PrintInt(x)));
        Debug.WriteLine("TestDelegate method name is {0}", GetMethodName(x => TestDelegate(x)));
    }
}

When I call TestGetMethodName() I get this output:

e.Body.NodeType is Call
PrintInt method name is PrintInt
e.Body.NodeType is Invoke
TestDelegate method name is ERROR

The goal is to get the name of the method that is assigned to TestDelegate. The "GetMethodName(x => PrintInt(x))" call is only there to prove that I'm doing it at least partly right. How can I get it to tell me that "TestDelegate method name is PrintInt"?

2条回答
【Aperson】
2楼-- · 2019-06-08 19:57
private static string GetMethodName( Expression<Action<int>> e )
{
    Debug.WriteLine( "e.Body.NodeType is {0}", e.Body.NodeType );
    MethodCallExpression mce = e.Body as MethodCallExpression;
    if ( mce != null ) {
        return mce.Method.Name;
    }

    InvocationExpression ie = e.Body as InvocationExpression;
    if ( ie != null ) {
        var me = ie.Expression as MemberExpression;
        if ( me != null ) {
            var prop = me.Member as PropertyInfo;
            if ( prop != null ) {
                var v = prop.GetValue( null ) as Delegate;
                return v.Method.Name;
            }
        }
    }
    return "ERROR";
}
查看更多
成全新的幸福
3楼-- · 2019-06-08 20:20

The answer is much simpler than I was making it. It's simply TestDelegate.GetMethodInfo().Name. No need for my GetMethodName function. I wasn't "using System.Reflection" and so Delegate.GetMethodInfo wasn't appearing in intellisense, and I somehow missed it in the docs. Thanks to HappyNomad for bridging the gap.

The working code is:

public class Test2
{
    public static Action<int> TestDelegate { get; set; }

    public static void PrintInt(int x)
    {
        Debug.WriteLine("int {0}", x);
    }

    public static void TestGetMethodName()
    {
        TestDelegate = PrintInt;
        Debug.WriteLine("TestDelegate method name is {0}", TestDelegate.GetMethodInfo().Name);
    }
}
查看更多
登录 后发表回答