反射-为什么C#中没有`fieldof`或`methodof`运算符?

它们的用法如下:

FieldInfo field = fieldof(string.Empty);
MethodInfo method1 = methodof(int.ToString);
MethodInfo method2 = methodof(int.ToString(IFormatProvider));

fieldof可以编译为IL,如下所示:

ldtoken <field>
call FieldInfo.GetFieldFromHandle

typeof可以编译为IL:

ldtoken <method>
call MethodBase.GetMethodFromHandle

每当使用typeof运算符时,您都会得到理想的“查找所有参考”结果。 不幸的是,一旦您进入字段或方法,您最终会受到讨厌的攻击。 我认为您可以执行以下操作...,也可以返回按名称获取字段。

public static FieldInfo fieldof<T>(Expression<Func<T>> expression)
{
    MemberExpression body = (MemberExpression)expression.Body;
    return (FieldInfo)body.Member;
}

public static MethodInfo methodof<T>(Expression<Func<T>> expression)
{
    MethodCallExpression body = (MethodCallExpression)expression.Body;
    return body.Method;
}

public static MethodInfo methodof(Expression<Action> expression)
{
    MethodCallExpression body = (MethodCallExpression)expression.Body;
    return body.Method;
}

public static void Test()
{
    FieldInfo field = fieldof(() => string.Empty);
    MethodInfo method1 = methodof(() => default(string).ToString());
    MethodInfo method2 = methodof(() => default(string).ToString(default(IFormatProvider)));
    MethodInfo method3 = methodof(() => default(List<int>).Add(default(int)));
}
Sam Harwell asked 2020-08-06T19:31:23Z
4个解决方案
35 votes

您实际上可以避免同时使用反射和lambda(.NET Framework 2.0)。 考虑以下类别:

public class methodof<T>
{
    private MethodInfo method;

    public methodof(T func)
    {
        Delegate del = (Delegate)(object)func;
        this.method = del.Method;
    }

    public static implicit operator methodof<T>(T methodof)
    {
        return new methodof<T>(methodof);
    }

    public static implicit operator MethodInfo(methodof<T> methodof)
    {
        return methodof.method;
    }
}

它的用法:

MethodInfo writeln = (methodof<Action>)Console.WriteLine;
MethodInfo parse = (methodof<Func<string, int>>)int.Parse;
MagnatLU answered 2020-08-06T19:31:57Z
22 votes

Eric Lippert(C#设计团队的成员)在这里对这个主题有很好的概述/讨论。 报价:

这是一个了不起的功能,几乎所有参与设计过程的人都希望我们能够做得到,但是出于很多实际的原因,我们选择不这样做。 如果有一天设计和实施它是我们可以使用有限预算的最佳方式,那么我们会做的。 在此之前,请使用反射。

Jason answered 2020-08-06T19:31:33Z
6 votes

@ 280Z28-当我找到您的问题和代码时,我们只是坐在那里想办法。 我们需要一个PropertyOf方法,所以我添加了它。 这是万一其他人需要它的情况。 谢谢伟大的问题。

     public static PropertyInfo PropertyOf<T>(Expression<Func<T>> expression)
    {
        MemberExpression body = (MemberExpression)expression.Body;
        PropertyInfo pi = body.Member as PropertyInfo;
        if (pi != null)
        {
            return pi;
        }
        else throw new ArgumentException("Lambda must be a Property.");
    } 

      [TestMethod()]
    public void MethodofPropertyOfTest<T>()
    {

        string foo = "Jamming";
        MethodInfo method1 = ReflectionHelper.Methodof(() => default(string).ToString());
        PropertyInfo prop = ReflectionHelper.PropertyOf(() => default(string).Length);
        Assert.AreEqual(method1.Invoke(foo, null), "Jamming");
        Assert.AreEqual(prop.GetGetMethod().Invoke(foo, null), foo.Length);
    }
Terence answered 2020-08-06T19:32:18Z
0 votes

这是一个通用类型的版本,可以使用F2重命名,而无需修改现有代码在示例中,方法名称为GetPKValue

var typFactory = typeof(FormFieldFactory<>).MakeGenericType(entity.GetType());
var methodName = new Func<object, object>(FormFieldFactory<object>.GetPKValue).Method.Name;

var theMethod =
    (Func<object, object>)Delegate.CreateDelegate(
        typeof(Func<object, object>)
        , typFactory.GetMethod(methodName)
    );
IlPADlI answered 2020-08-06T19:32:38Z
translate from https://stackoverflow.com:/questions/1213862/why-is-there-not-a-fieldof-or-methodof-operator-in-c