Почему в С# нет оператора `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
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)));
}
Ответы
Ответ 1
Эрик Липперт (в команде разработчиков С#) имеет отличный обзор/обсуждение по этой теме здесь. Цитировать:
Его удивительная особенность, которую почти все, кто участвует в процессе проектирования, хотел бы сделать, но есть хорошие практические причины, по которым мы не хотим этого делать. Если наступает день, когда он разрабатывается и реализуется, это лучший способ, которым мы могли бы потратить наш ограниченный бюджет, хорошо сделайте это. До тех пор используйте Reflection.
Ответ 2
Вы можете избежать использования как отражения, так и lambdas (.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;
Ответ 3
@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);
}
Ответ 4
это версия общего типа, которая может использовать 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)
);
Ответ 5
Я вспоминаю день, когда размышление становится таким легким. Если вы считаете, что динамический SQL был плохим, это привело бы к чему-то еще в десятки раз.
Представьте себе, изменив имя свойства и вам придется беспокоиться о ошибках времени выполнения./Дрожь