Get property name and type using lambda expression
Asked Answered
I

4

41

I am trying to write a function that will pull the name of a property and the type using syntax like below:

private class SomeClass
{
    Public string Col1;
}

PropertyMapper<Somewhere> propertyMapper = new PropertyMapper<Somewhere>();
propertyMapper.MapProperty(x => x.Col1)

Is there any way to pass the property through to the function without any major changes to this syntax?

I would like to get the property name and the property type.

So in the example below i would want to retrieve

Name = "Col1" and Type = "System.String"

Can anyone help?

Idyllic answered 7/11, 2008 at 23:5 Comment(3)
What's the bigger picture? Why not just pass "Col1" as a string name and use reflection to find that member? What motivates the lambda?Lilienthal
I'm working on an in house ORM for my work. I want to easily support changing property names without having to search string all over the place, plus it give (in my opinion) a clean syntaxIdyllic
Does this answer your question? Retrieving Property name from lambda expressionConnotation
G
66

Here's enough of an example of using Expressions to get the name of a property or field to get you started:

public static MemberInfo GetMemberInfo<T, U>(Expression<Func<T, U>> expression)
{
    var member = expression.Body as MemberExpression;
    if (member != null)
        return member.Member;

    throw new ArgumentException("Expression is not a member access", "expression");
}

Calling code would look like this:

public class Program
{
    public string Name
    {
        get { return "My Program"; }
    }

    static void Main()
    {
        MemberInfo member = ReflectionUtility.GetMemberInfo((Program p) => p.Name);
        Console.WriteLine(member.Name);
    }
}

A word of caution, though: the simple statment of (Program p) => p.Name actually involves quite a bit of work (and can take measurable amounts of time). Consider caching the result rather than calling the method frequently.

Gussiegussman answered 7/11, 2008 at 23:20 Comment(2)
Always remember that a lambda expression can be converted into either a delegate or an expression tree.Halide
Caveat: GetMemberInfo implementation is not very safe - #6659169. That said you can use it just to read the name. But the returned member info itself wont be accurate.Saleme
L
4

This can be easily done in C# 6. To get the name of property use nameof operator.

nameof(User.UserId)

and to get type of property use typeof operator.

typeof(User.UserId)
Lsd answered 22/6, 2016 at 11:32 Comment(0)
S
3

I found this very useful.

public class PropertyMapper<T>
{
    public virtual PropertyInfo PropertyInfo<U>(Expression<Func<T, U>> expression)
    {
        var member = expression.Body as MemberExpression;
        if (member != null && member.Member is PropertyInfo)
            return member.Member as PropertyInfo;

        throw new ArgumentException("Expression is not a Property", "expression");
    }

    public virtual string PropertyName<U>(Expression<Func<T, U>> expression)
    {
        return PropertyInfo<U>(expression).Name;
    }

    public virtual Type PropertyType<U>(Expression<Func<T, U>> expression)
    {
        return PropertyInfo<U>(expression).PropertyType;
    }
}

I made this little class to follow the original request. If you need the name of the property you can use it like this:

PropertyMapper<SomeClass> propertyMapper = new PropertyMapper<SomeClass>();
string name = propertyMapper.PropertyName(x => x.Col1);
Shirtmaker answered 5/11, 2014 at 20:14 Comment(0)
N
3

I just thought I would put this here to build on the previous approach.

public static class Helpers
{
    public static string PropertyName<T>(Expression<Func<T>> expression)
    {
        var member = expression.Body as MemberExpression;
        if (member != null && member.Member is PropertyInfo)
            return member.Member.Name;

        throw new ArgumentException("Expression is not a Property", "expression");
    }
}

You can then call it in the following fashion:

Helpers.PropertyName(() => TestModel.TestProperty);

I should also point out that with VS 2015 and C# 6.0 you can simply use nameof.

https://msdn.microsoft.com/en-us/library/dn986596.aspx

Nagaland answered 7/4, 2016 at 21:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.