-1

I want to be able to call this method like this:

test.TestMethod<From, To>(to => to.Prop1);

and have IDE auto-complete properties from To. In TestMethod, I want to pull the name of the property. In this case Prop1. It seems like its kind of working, but I'm not sure about the Expression<Func<TTo, object>>, especially the object part.

public class Test
{
    public void TestMethod<TFrom, TTo>(Expression<Func<TTo, object>> p)
    {
    }
}

It does what its supposed to now if I recurse through p, I can get to the name, but it doesn't look right to me, especially since pulling the name of the prop looks like:

((MemberExpression)((UnaryExpression)(((LambdaExpression)p).Body)).Operand)).Member.Name

Any way to do this cleaner?

Nkosi
  • 235,767
  • 35
  • 427
  • 472
SledgeHammer
  • 7,338
  • 6
  • 41
  • 86
  • 1
    Perhaps something like this would be useful? http://stackoverflow.com/questions/31261955/nameof-expression-in-net-framework-4/31262225#31262225 – Rob May 08 '16 at 23:32
  • "I want to (...) have IDE auto-complete properties" - as this is rather IDE-specific, you should add the appropriate tag for the IDE (maybe Visual Studio? Or SharpDevelop? Or MonoDevelop?) to your question. – O. R. Mapper May 08 '16 at 23:32
  • @Rob - hmm... that only works on "this". Not on TTo. Method needs to be strongly typed to TTo. – SledgeHammer May 08 '16 at 23:49
  • If you are using C#6 there is a built-in `nameof` keyword. – Cheng Chen May 09 '16 at 02:41

1 Answers1

0

Here is a helper class that will inspect the expression and extract the member info of the property

using System.Linq.Expressions;
using System.Reflection;

/// <summary>
/// Extension for <see cref="Expression"/>.
/// </summary>
public static class ExpressionExtensions {
    /// <summary>
    /// Converts an expression into a <see cref="System.Reflection.MemberInfo"/>.
    /// </summary>
    /// <param name="expression">The expression to convert.</param>
    /// <returns>The member info.</returns>
    public static MemberInfo GetMemberInfo(this Expression expression) {
        var lambda = (LambdaExpression)expression;

        MemberExpression memberExpression;
        if (lambda.Body is UnaryExpression) {
            var unaryExpression = (UnaryExpression)lambda.Body;
            memberExpression = (MemberExpression)unaryExpression.Operand;
        }
        else
            memberExpression = (MemberExpression)lambda.Body;

        return memberExpression.Member;
    }

}

with that you can then extract the name as intended...

public class Test {
    public void TestMethod<TFrom, TTo>(Expression<Func<TTo>> property) {
        var memberName = property.GetMemberInfo().Name;
        //...other code
    }
}

You will then be able to call this method like this...

test.TestMethod<From, To>(to => to.Prop1);

...and get the property name.

Nkosi
  • 235,767
  • 35
  • 427
  • 472