0

I want to increase the maintainability by passing a delegate rather than a const string. What I've done is like this;

var propertyName = SprintMetrics.GetNameOf(metric => metric.Productivity); //Should be : "Productivity"

and:

public static string GetNameOf(Func<SprintMetrics, double> valueFunc)
{
    return valueFunc.GetMethodInfo().Name; //Result is : <Excute>b_40....
}

During the debug, I walked throw "valueFunc", and there was no "Productivity" anywhere.

Is there any way to get the property's name "Productivity"? Thanks.


According to Access Denied's answer below, it can be done by both of the following:

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

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

2 Answers 2

2

I walked throw "valueFunc", and there was no "Productivity" anywhere.

That's because valueFunc is simply an anonymous function that returns the value of the Productivity property since that's how you defined the delegate.

If instead you want to inspect the delegate then use Expression instead:

public static string GetNameOf<T>(Expression<Func<SprintMetrics, T>> valueFunc)
{
    var expression = (MemberExpression)valueFunc.Body;
    return expression.Member.Name;
}

Of course, you'll want to add error handling (what if action.Body is not a MemberExpression? What if it refers to a field and not a property?). You can see a more complete example in this answer

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for the tip! I would study more about the expression things :) There would be much to explore!
1

You can use C# keyword nameof which was designed for this task:

var propertyName = nameof(metric.Productivity)

For more info take a look at the following article.

As for your code in order to extract property name from lambda expressions you can use the following method (And there is no need to have input Func parameter in that case):

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;
}

And you can call it this way: GetPropertyName(() => metric.Productivity)

1 Comment

Great! "nameof" could be the easiest way to do it! Thanks a lot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.