If you use an ORM (such as EF or NHibernate), you end up with classes for each mapped table, and its fields mapped to properties:
public class Foo { public int FooID { get; set; } public string Name { get; set; } }
To get the name of each property as a string, use the following generic method:
public class Tools { public static string GetPropertyName<P, T>(Expression<Func<P, T>> expression) { MemberExpression memberExpression = (MemberExpression)expression.Body; return memberExpression.Member.Name; } }
If you call this method explicitly, you need to pass the types of both the class and the property type in the invocation, e.g.:
Tools.GetPropertyName<Foo, string>(f => f.Name)
If you use a generic class declaring the data class, the compiler can infer the type of the property, and there is no need to provide both types:
public class Test<Class> { public static string GetPropertyName<T>(Expression<Func<Class, T>> Field) { return Tools.GetPropertyName(Field); } } Test<Foo>.GetPropertyName( f => f.Name );
Sometimes (*) the compiler includes a Convert function into the expression tree to convert between the original and target data type of the property. We can extend the GetPropertyName() function to take care of the Convert function:
public static string GetPropertyName<P, T>(Expression<Func<P, T>> expression) { if (expression.Body is UnaryExpression) { UnaryExpression unex = (UnaryExpression)expression.Body; if (unex.NodeType == ExpressionType.Convert) { Expression ex = unex.Operand; MemberExpression mex = (MemberExpression)ex; return mex.Member.Name; } } MemberExpression memberExpression = (MemberExpression)expression.Body; return memberExpression.Member.Name; }
(*) I met this condition when dealing with overloaded generic methods, and the C# compiler could not infer the correct method from the property types given as parameters.
Exactly what I needed. I have combined first two points in one class
public class NHProperty
{
public static string Name(Expression<Func> field)
{
return NHProperty.GetPropertyName(field);
}
protected static string GetPropertyName(Expression<Func> expression)
{
MemberExpression memberExpression = (MemberExpression)expression.Body;
return memberExpression.Member.Name;
}
I know that I’m asking too much but is there any way for nested property (ew. Studies.ID or Studies.Class.Name )to convert to string? Of Course I can concatenate all parts but it will look horrible.
Jacek, I guess you’d have to look at the structure of the value of expression to retrieve nested properties
Pingback: Get Name of Nested Property as String Value « devioblog
Nice!
Pingback: Constructing Type-Safe SQL Statements from ORM Classes | devioblog