假设我有这个对象
class SomeObject
{
public int id { get; set; }
public string name {get;set;}
public string description {get;set;}
public anotherObject obj {get;set;}
}
此扩展方法,如果该属性名称的名称作为参数发送,则从列表中删除PropertyInfo
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");
这不错,但我试图找到一种方法来避免将属性名称作为字符串发送,有没有办法使这个函数使用lambda表达式,以便我可以在Visual Studio中获取建议,同时编写属性除了?
更新:根据所选答案,以下内容也支持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;
}
答案 0 :(得分: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));
}