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"); } } }
1. | Decode Member Access Expression | ||
2. | Get Member Name |