asp.net C #: получить имя свойства в делегате - PullRequest
0 голосов
/ 07 сентября 2018

Я хочу повысить удобство сопровождения, передавая делегат, а не константную строку. То, что я сделал, так:

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», и нигде не было «Производительности».

Есть ли способ получить название свойства "Производительность"? Благодарю.


Согласно приведенному ниже ответу «Отказано в доступе», это можно сделать одним из следующих способов:

var p = nameof(SprintMetrics.Productivity); //"Productivity"

var metrics = new SprintMetrics();
p = nameof(metrics.Productivity); //"Productivity"

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Я прошёл, бросил «valueFunc», и нигде не было «Производительности».

Это потому, что 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? Что если он ссылается на поле, а не на свойство?). Вы можете увидеть более полный пример в этот ответ

0 голосов
/ 07 сентября 2018

Вы можете использовать ключевое слово C # nameof, которое было разработано для этой задачи:

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)

...