I'd like to pass property names to a function without using of magic strings.
Something like:
Get<ObjectType>(x=>x.Property1);
where Property1 is a property of type ObjectType.
What would the method implementation look like ?
This can be achieved using Expressions:
// requires object instance, but you can skip specifying T static string GetPropertyName<T>(Expression<Func<T>> exp) { return (((MemberExpression)(exp.Body)).Member).Name; } // requires explicit specification of both object type and property type static string GetPropertyName<TObject, TResult>(Expression<Func<TObject, TResult>> exp) { // extract property name return (((MemberExpression)(exp.Body)).Member).Name; } // requires explicit specification of object type static string GetPropertyName<TObject>(Expression<Func<TObject, object>> exp) { var body = exp.Body; var convertExpression = body as UnaryExpression; if(convertExpression != null) { if(convertExpression.NodeType != ExpressionType.Convert) { throw new ArgumentException("Invalid property expression.", "exp"); } body = convertExpression.Operand; } return ((MemberExpression)body).Member.Name; }
Usage:
var x = new ObjectType(); // note that in this case we don't need to specify types of x and Property1 var propName1 = GetPropertyName(() => x.Property1); // assumes Property2 is an int property var propName2 = GetPropertyName<ObjectType, int>(y => y.Property2); // requires only object type var propName3 = GetPropertyName<ObjectType>(y => y.Property3);
Update: fixed GetPropertyName<TObject>(Expression<Func<TObject, object>> exp)
for properties returning value types.
class Foo
{
public string Bar { get; set; }
}
class Program
{
static void Main()
{
var result = Get<Foo, string>(x => x.Bar);
Console.WriteLine(result);
}
static string Get<T, TResult>(Expression<Func<T, TResult>> expression)
{
var me = expression.Body as MemberExpression;
if (me != null)
{
return me.Member.Name;
}
return null;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With