2013-12-21 4 views
2

Предположим, я имел этот объектParams к лямбда-выражения

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

и этот метод расширения, который удаляет с PropertyInfo из списка, если имя этого свойства nameis послал в качестве параметра

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(); 
     } 

и я использую его как следующее:

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

, что неплохо, но я пытаюсь найти способ избежать отправки имена свойств как строки, есть ли способ заставить эту функцию использовать лямбда-выражения, чтобы я мог получать предложения в визуальной студии при написании свойств до Except?

Update: на основе выбранного ответа на следующий поддерживает 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; 
      } 

ответ

3
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)); 
} 
Смежные вопросы