我试图在具有很多属性的对象列表中进行搜索.寻找一个优雅的解决方案,例如lambda表达式,它可以根据搜索字符串返回结果.这是我的简化数据源.我的实际Customer
课程有更多属性:
public static class CustomerDataSource
{
public static List<Customer> customerData
{
get
{
Customer customer1 = new Customer() { name = "Bert", address = "London" };
Customer customer2 = new Customer() { name = "Jon", address = "New York" };
List<Customer> listCustomers = new List<Customer>();
listCustomers.Add(customer1);
listCustomers.Add(customer2);
return listCustomers;
}
}
}
public class Customer
{
public string name { get; set; }
public string address { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
什么样的语句可以返回Customer
包含'searchstring'的所有s.例如,如果搜索字符串为'e',则它应返回两者customer1
,customer2
因为包含'e' 的name
和address
属性customer1
.
我可以编写类似下面的内容,但后来我必须为每个属性编写一行代码:
var list = CustomerDataSource.customerData.FindAll(x => x.address.Contains("e"));
var list2 = CustomerDataSource.customerData.FindAll(x => x.name.Contains("e"));
Run Code Online (Sandbox Code Playgroud)
您可以使用Reflection获取所有属性并将其与LINQ结合使用:
var list = CustomerDataSource
.customerData
.Where(c => c.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Any(pi => pi.GetValue(c).ToString().Contains("York")))
.ToList();
Run Code Online (Sandbox Code Playgroud)
以上代码仅返回customer2
.
但是,如果您现在想要在查询期间搜索所有属性,我会采用归因方法 - 使用您的自定义属性标记要搜索的属性:
[AttributeUsage(AttributeTargets.Property)]
sealed class SearchableAttribute : Attribute
{
public SearchableAttribute()
{
}
}
Run Code Online (Sandbox Code Playgroud)
然后相应地修改您的类,例如,标记只name
应该使用:
public class Customer
{
[Searchable]
public string name { get; set; }
public string address { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
并略微修改上面的LINQ查询:
var list = CustomerDataSource
.customerData
.Where(c => c.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(pi => pi.GetCustomAttribute<SearchableAttribute>() != null)
.Any(pi => pi.GetValue(c).ToString().Contains("York")))
.ToList();
Run Code Online (Sandbox Code Playgroud)
注意:正如Sam所说,aboce代码假定您对具有适当.ToString()
实现类型的属性感兴趣.因此,在数组的情况下它不会起作用.您必须进一步修改此代码以满足您的需求.以下是使用合适.ToString()
方法对数组进行额外处理的示例:
var list = CustomerDataSource
.customerData
.Where(c => c.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(pi => pi.GetCustomAttribute<SearchableAttribute>() != null)
.Any(pi => pi.PropertyType.IsArray
? (pi.GetValue(c) as IEnumerable<object>)
.Any(o => o.ToString().Contains("Paris"))
: pi.GetValue(c).ToString().Contains("Paris")))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
182 次 |
最近记录: |