LINQ C#

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace WindowsPhoneMvp.Util
{
    public class Property
    {
        /// 
        /// Returns the string name of a property, this allows type / member safety
        /// 

        /// () => obj.Name
        /// Name
        public static string GetFor(Expression> 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>[] propertyNameLambda)
        {
            return propertyNameLambda
                .Select(property => property.Body)
                .OfType()
                .Select(member => member.Member.Name)
                .Concat(propertyNameLambda
                    .Select(property => property.Body)
                    .OfType()
                    .Select(member => member.Operand)
                    .OfType()
                    .Select(member => member.Member.Name))
                .ToArray();
        }
        /// 
        /// Returns the string name of a property, this allows type / member safety
        /// 

        /// Type of objects who's properties to evaluate
        /// obj => obj.Name
        /// Name
        public static string For(Expression> propertyNameLambda)
        {
            var memberInfo = GetMemberInfo(propertyNameLambda);
            if(memberInfo != null)
                return memberInfo.Name;
            throw new ArgumentException("Could not determine property name.", "propertyNameLambda");
        }
        /// 
        /// Returns the string name of a property, this allows type / member safety
        /// 

        ///  
        /// Adding the TRetVal parameter allows more efficient Lambda expressions (doesn't create the Convert(p => p.ID) function)
        /// also helps in Generic Type inference
        /// 

        public static string For(Expression> propertyNameLambda)
        {
            var memberInfo = GetMemberInfo(propertyNameLambda);
            if(memberInfo != null)
                return memberInfo.Name;
            throw new ArgumentException("Could not determine property name.", "propertyNameLambda");
        }
        static MemberInfo GetMemberInfo(Expression> 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(Expression> 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");
        }
    }
}