他们可以使用如下:
FieldInfo field = fieldof(string.Empty);
MethodInfo method1 = methodof(int.ToString);
MethodInfo method2 = methodof(int.ToString(IFormatProvider));
fieldof
可以被编译为IL为:
ldtoken <field>
call FieldInfo.GetFieldFromHandle
methodof
可以被编译成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)));
}
埃里克利珀(在C#设计团队)对这个话题很好的概括/讨论在这里 。 报价:
这是一个真棒功能,几乎每个人都参与到设计过程中希望我们可以做,但也有我们为什么不选择好实际的原因。 如果没有设计它,实现它是我们可以用我们的预算有限的最好方式,当一天到来时,我们会做到这一点。 在此之前,使用反射。
实际上,你可以尽量避免使用反射和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;
@ 280Z28 - 我们只是坐下来弄清楚如何做到这一点的时候,我发现你的问题和代码。 我们需要一个性能中的方法,所以我加入吧。 这是以防别人需要它。 THX的大问题。
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);
}
这是一个通用型的版本,可以用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)
);
我后悔的一天,当反射变得如此简单。 如果你认为动态SQL是坏的,这将导致一些十几次差。
试想一下,更改属性名称,不必担心运行时错误。 /不寒而栗