Я хочу повысить ремонтопригодность, передав делегат, а не константную строку. Я сделал вот что;
var propertyName = SprintMetrics.GetNameOf(metric => metric.Productivity); //Should be : "Productivity"
а также:
public static string GetNameOf(Func<SprintMetrics, double> valueFunc)
{
return valueFunc.GetMethodInfo().Name; //Result is : <Excute>b_40....
}
Во время отладки я прошел через "valueFunc", а "Productivity" нигде не было.
Есть ли способ получить название собственности "Продуктивность"? Спасибо.
Согласно ответу "Доступ запрещен" ниже, это можно сделать двумя из следующих способов:
var p = nameof(SprintMetrics.Productivity); //"Productivity"
var metrics = new SprintMetrics();
p = nameof(metrics.Productivity); //"Productivity"
Вы можете использовать ключевое слово nameof в C#, которое было разработано для этой задачи:
var propertyName = nameof(metric.Productivity)
Для получения дополнительной информации взгляните на следующий статья.
Что касается вашего кода, чтобы извлечь имя свойства из лямбда-выражений, вы можете использовать следующий метод (и в этом случае нет необходимости иметь входной параметр Func):
public static string GetPropertyName<TProperty>(Expression<Func<TProperty>> propertyLambda)
{
MemberExpression member = propertyLambda.Body as MemberExpression;
if (member == null)
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a method, not a property.",
propertyLambda.ToString()));
PropertyInfo propInfo = member.Member as PropertyInfo;
if (propInfo == null)
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a field, not a property.",
propertyLambda.ToString()));
return propInfo.Name;
}
И назвать это можно так: GetPropertyName(() => metric.Productivity)
I walked throw "valueFunc", and there was no "Productivity" anywhere.
Это потому, что valueFunc
- это просто анонимная функция, которая возвращает значение свойства Productivity
, поскольку именно так вы определили делегата.
Если вместо этого вы хотите осмотреть делегата, используйте вместо этого Expression
:
public static string GetNameOf<T>(Expression<Func<SprintMetrics, T>> valueFunc)
{
var expression = (MemberExpression)valueFunc.Body;
return expression.Member.Name;
}
Конечно, вы захотите добавить обработку ошибок (что, если action.Body
не является MemberExpression
? Что, если он относится к полю, а не к свойству?). Вы можете увидеть более полный пример в этот ответ
Большое спасибо за совет! Я хотел бы больше узнать о выражениях :) Было бы много чего исследовать!
Большой! "nameof" может быть самым простым способом сделать это! Большое спасибо.