代码之家  ›  专栏  ›  技术社区  ›  berko

检索在func中执行的被调用方法的名称

  •  2
  • berko  · 技术社区  · 15 年前

    我想得到被委托为func的方法的名称。

    Func<MyObject, object> func = x => x.DoSomeMethod();
    string name = ExtractMethodName(func); // should equal "DoSomeMethod"
    

    我怎样才能做到这一点?

    --吹牛的权利--

    制作 ExtractMethodName 还可以使用属性调用,让它返回该实例中的属性名。

    如。

    Func<MyObject, object> func = x => x.Property;
    string name = ExtractMethodName(func); // should equal "Property"
    
    3 回复  |  直到 9 年前
        1
  •  11
  •   Dustin Campbell    15 年前

    看,马!没有表情树!

    这里有一个快速的、脏的、特定于实现的版本,它从基础lambda的IL流中获取元数据标记并解析它。

    private static string ExtractMethodName(Func<MyObject, object> func)
    {
        var il = func.Method.GetMethodBody().GetILAsByteArray();
    
        // first byte is ldarg.0
        // second byte is callvirt
        // next four bytes are the MethodDef token
        var mdToken = (il[5] << 24) | (il[4] << 16) | (il[3] << 8) | il[2];
        var innerMethod = func.Method.Module.ResolveMethod(mdToken);
    
        // Check to see if this is a property getter and grab property if it is...
        if (innerMethod.IsSpecialName && innerMethod.Name.StartsWith("get_"))
        {
            var prop = (from p in innerMethod.DeclaringType.GetProperties()
                        where p.GetGetMethod() == innerMethod
                        select p).FirstOrDefault();
            if (prop != null)
                return prop.Name;
        }
    
        return innerMethod.Name;
    }
    
        2
  •  0
  •   jcopenha    15 年前

    我认为在一般情况下这是不可能的。如果你有:

    Func<MyObject, object> func = x => x.DoSomeMethod(x.DoSomeOtherMethod());
    

    你期待什么?

    也就是说,您可以使用反射来打开func对象,看看它在内部做什么,但是您只能在某些情况下解决它。

        3
  •  0
  •   Community Reversed Engineer    7 年前

    查看我的黑客回答:

    Why is there not a `fieldof` or `methodof` operator in C#?

    过去我用另一种方法 Func 而不是 Expression<Func<...>> 但是我对结果不太满意。这个 MemberExpression 用于检测我的 fieldof 方法将返回 PropertyInfo 当使用属性时。

    编辑1:这适用于问题的一个子集:

    Func<object> func = x.DoSomething;
    string name = func.Method.Name;
    

    编辑2:标记我的人应该花点时间了解这里发生了什么。表达式树可以隐式地与lambda表达式一起使用,并且是在此处获取特定请求信息的最快、最可靠的方法。

    推荐文章