Linq Reflection
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace WindowsPhoneMvp.Util
{
public class Property
{
/// <summary>
/// Returns the string name of a property, this allows type / member safety
/// </summary>
/// <param name="propertyNameLambda">() => obj.Name</param>
/// <returns>Name</returns>
public static string GetFor(Expression<Func<object>> propertyNameLambda)
{
MemberExpression member;
if(propertyNameLambda.Body is UnaryExpression)
member = ((UnaryExpression)propertyNameLambda.Body).Operand as MemberExpression;
else
member = propertyNameLambda.Body as MemberExpression;
if (member != null)
return member.Member.Name;
throw new ArgumentException("Could not determine property name.", "propertyNameLambda");
}
public static string[] GetFor(params Expression<Func<object>>[] propertyNameLambda)
{
return propertyNameLambda
.Select(property => property.Body)
.OfType<MemberExpression>()
.Select(member => member.Member.Name)
.Concat(propertyNameLambda
.Select(property => property.Body)
.OfType<UnaryExpression>()
.Select(member => member.Operand)
.OfType<MemberExpression>()
.Select(member => member.Member.Name))
.ToArray();
}
/// <summary>
/// Returns the string name of a property, this allows type / member safety
/// </summary>
/// <typeparam name="T">Type of objects who's properties to evaluate</typeparam>
/// <param name="propertyNameLambda">obj => obj.Name</param>
/// <returns>Name</returns>
public static string For<T>(Expression<Func<T, object>> propertyNameLambda)
{
var memberInfo = GetMemberInfo(propertyNameLambda);
if(memberInfo != null)
return memberInfo.Name;
throw new ArgumentException("Could not determine property name.", "propertyNameLambda");
}
/// <summary>
/// Returns the string name of a property, this allows type / member safety
/// </summary>
/// <remarks>
/// Adding the TRetVal parameter allows more efficient Lambda expressions (doesn't create the Convert(p => p.ID) function)
/// also helps in Generic Type inference
/// </remarks>
public static string For<T, TRetVal>(Expression<Func<T, TRetVal>> propertyNameLambda)
{
var memberInfo = GetMemberInfo(propertyNameLambda);
if(memberInfo != null)
return memberInfo.Name;
throw new ArgumentException("Could not determine property name.", "propertyNameLambda");
}
static MemberInfo GetMemberInfo<T, TRetVal>(Expression<Func<T, TRetVal>> propertyNameLambda)
{
MemberExpression member;
if(propertyNameLambda.Body is UnaryExpression)
member = ((UnaryExpression)propertyNameLambda.Body).Operand as MemberExpression;
else
member = propertyNameLambda.Body as MemberExpression;
return member != null ? member.Member : null;
}
public static PropertyInfo InfoFor<T>(Expression<Func<T, object>> propertyNameLambda)
{
MemberExpression member;
if (propertyNameLambda.Body is UnaryExpression)
member = ((UnaryExpression)propertyNameLambda.Body).Operand as MemberExpression;
else
member = propertyNameLambda.Body as MemberExpression;
if (member != null)
{
return member.Member as PropertyInfo;
}
throw new ArgumentException("Could not determine property name.", "propertyNameLambda");
}
}
}
Related examples in the same category