Get property name and type using lambda expression
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?
Solution 1:
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.
Solution 2:
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)
Solution 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);
Solution 4:
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