FPGA
FPGA

Reputation: 3855

Params to a lambda expression

Suppose i had this object

class SomeObject
    {
        public int id { get; set; }
        public string name {get;set;}
        public string description {get;set;}
        public anotherObject obj {get;set;}
    }

and this extension method which removes the a PropertyInfo from a list if the name of that property nameis sent as parameter

public static IList<PropertyInfo> Except(this IList<PropertyInfo> Properties, params string[] PropertiesToExecludeNames)
       {
           return Properties.Where(p => !(PropertiesToExecludeNames ?? Enumerable.Empty<String>()).Any(s => s == p.Name)).ToList();
       }

and i use it as the following

var someObject = new SomeObject();
var Properties = someObject.GetType().GetProperties();
Properties = Properties.Except("name","obj");

which isn't bad, but i am trying to find a way to avoid sending property names as strings, is there a way to make this function use a lambda expressions so that i could get suggestions in visual studio while writing the properties to Except?

Update: based on the selected answer the following also supports UnaryExpressions

    public static IEnumerable<PropertyInfo> GetPropertyInfosExcept<T>(this T obj, params Expression<Func<T, object>>[] lambda)
            {
                HashSet<string> set = new HashSet<string>(
                        lambda.Select(l => l.GetMemberInfo() as PropertyInfo)
                              .Select(x => x.Name));
                return typeof(T).GetProperties().Where(p => !set.Contains(p.Name));
            }


public static MemberInfo GetMemberInfo(this LambdaExpression expression)
            {
                return expression.Body is MemberExpression ? ((MemberExpression)expression.Body).Member : ((MemberExpression)(((UnaryExpression)expression.Body).Operand)).Member;
            }

Upvotes: 2

Views: 136

Answers (1)

L.B
L.B

Reputation: 116118

var pInfos = new SomeObject().GetPropertyInfosExcept(x => x.obj, x => x.name)
             .ToList();

public static IEnumerable<PropertyInfo> GetPropertyInfosExcept<T>(
                          this T obj, params Expression<Func<T, object>>[] lambda)
{
    HashSet<string> set = new HashSet<string>(
            lambda.Select(l => (l.Body as MemberExpression).Member as PropertyInfo)
                  .Select(x=>x.Name)
        );

    return typeof(T).GetProperties().Where(p => !set.Contains(p.Name));
}

Upvotes: 3

Related Questions