I would like to be able to retrieve the name of a property of a type using a strongly typed syntax. I already got a function to get a property name of an instance:
public static string PropertyName<T, TReturn>(this T obj, Expression<Func<T, TReturn>> property) where T : class
{
MemberExpression body = (MemberExpression) property.Body;
if (body == null) throw new ArgumentException("The provided expression did not point to a property.");
return body.Member.Name;
}
Which can be called like this:
Car car = new Car();
car.PropertyName(x => x.Wheels) //returns "Wheels"
I'm trying to create another function that could support the following:
Type t = Typeof(Car);
t.PropertyName(x => x.Wheels) //should return "Wheels"
Or just (even better!):
Car.PropertyName(x => x.Wheels)
How would I go about this?
You can rewrite your method to use it without creating an instance:
var prop = ReflectionHelper.PropertyName<Car>(x => x.Wheels);
because your don't use obj
inside because you don't need it:
public static class ReflectionHelper
{
public static string PropertyName<T>(Expression<Func<T, object>> property) where T : class
{
MemberExpression body = (MemberExpression)property.Body;
return body.Member.Name;
}
}
Note that the return type doesn't have to be strongly-typed, it can be just object
.
@abatishchev example only works if Wheels
is a reference type.
If you have the following
public class Car
{
public int ID;
}
And you try to call this
var prop = ReflectionHelper.PropertyName<Car>(x => x.ID);
You'll get the following exception
InvalidCastException: Unable to cast object of type 'System.Linq.Expressions.UnaryExpression' to type 'System.Linq.Expressions.MemberExpression'.
I think this has to do with the fact that you are passing a value type to the expression, so it has to be boxed into an object. If you pass a reference type, it doesn't need to be boxed to object.
What you can do instead is this:
var prop = ReflectionHelper.PropertyName((Car x) => x.ID);
public static class ReflectionHelper
{
public static string PropertyName<T, P>(Expression<Func<T, P>> property)
where T : class
{
MemberExpression body = (MemberExpression)property.Body;
return body.Member.Name;
}
}