检索 Func 中执行的调用方法的名称

发布于 2024-07-29 11:31:47 字数 461 浏览 4 评论 0 原文

我想获取作为 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"

I would like to get the name of the method that is being delegated as a Func.

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

How can I achieve this?

-- For bragging rights --

Make ExtractMethodName also work with a property invocation, having it return the property name in that instance.

eg.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

简美 2024-08-05 11:31:48

瞧,妈! 没有表情树!

这是一个快速、肮脏且特定于实现的版本,它从底层 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;
}

Look Ma! No expression trees!

Here's a quick, dirty and implementation-specific version that grabs the metadata token from the IL stream of the underlying lambda and resolves it.

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;
}
离笑几人歌 2024-08-05 11:31:48

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

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

你会期望什么?

话虽这么说,您可以使用反射来打开 Func 对象并查看它的内部功能,但您只能在某些情况下解决它。

I don't think this is possible in the general case. What if you had:

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

What would you expect?

That being said, you could use reflection to open up the Func object and see what it does inside, but you'll only be able to solve it for certain cases.

污味仙女 2024-08-05 11:31:48

在这里查看我的黑客答案:

为什么会有不是 C# 中的“fieldof”或“methodof”运算符?

过去我用另一种方式使用 Func 而不是 Expression> ;,但我对结果不太满意。 当使用属性时,用于检测 fieldof 方法中字段的 MemberExpression 将返回 PropertyInfo

编辑#1:这适用于问题的一部分:

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

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

Check out my hack answer here:

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

In the past I did it another way that used Func instead of Expression<Func<...>>, but I was much less pleased with the result. The MemberExpression used to detect the field in my fieldof method will return a PropertyInfo when a property is used.

Edit #1: This works for a subset of the problem:

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

Edit #2: Whoever marked me down should take a second to realize what's going on here. The expression trees can be implicitly used with lambda expressions and are the fastest, most reliable way to get the specific requested information here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文