我有以下功能,可以在类上搜索基于字符串的属性以进行文本匹配,我想缓存'属性' Match()中的变量,因此每次运行类对象列表时都不会刷新。
public bool Match<T>(T item, string searchTerm)
{
//You should cache the results of properties here for max perf.
IEnumerable<Func<T, string>> properties = GetPropertyFunctions<T>();
bool match = properties.Select(prop => prop(item)).Any(value => value != null && value.ToLower().Contains(searchTerm.ToLower()));
return match;
}
public IEnumerable<Func<T, string>> GetPropertyFunctions<T>()
{
var stringProperties = GetStringPropertyFunctions<T>();
var decimalProperties = GetDecimalPropertyFunctions<T>();
return stringProperties.Concat(decimalProperties);
}
public IEnumerable<Func<T, string>> GetStringPropertyFunctions<T>()
{
var propertyInfos = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty)
.Where(p => p.PropertyType == typeof(string)).ToList();
var properties = propertyInfos.Select(GetStringPropertyFunc<T>);
return properties;
}
public Func<T, string> GetStringPropertyFunc<T>(PropertyInfo propInfo)
{
ParameterExpression x = System.Linq.Expressions.Expression.Parameter(typeof(T), "x");
Expression<Func<T, string>> expression = System.Linq.Expressions.Expression.Lambda<Func<T, string>>(System.Linq.Expressions.Expression.Property(x, propInfo), x);
Func<T, string> propertyAccessor = expression.Compile();
return propertyAccessor;
}
public IEnumerable<Func<T, string>> GetDecimalPropertyFunctions<T>()
{
var propertyInfos = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty)
.Where(p => p.PropertyType == typeof(decimal)).ToList();
var properties = propertyInfos.Select(GetDecimalPropertyFunc<T>);
return properties;
}
public Func<T, string> GetDecimalPropertyFunc<T>(PropertyInfo propInfo)
{
ParameterExpression x = System.Linq.Expressions.Expression.Parameter(typeof(T), "x");
Expression<Func<T, decimal>> expression = System.Linq.Expressions.Expression.Lambda<Func<T, decimal>>(System.Linq.Expressions.Expression.Property(x, propInfo), x);
Func<T, decimal> propertyAccessor = expression.Compile();
return (T item) => propertyAccessor(item).ToString();
}
答案 0 :(得分:1)
public static class FullTextSearch<T>
{
private List<Func<T, string>> _properties;
static FullTextSearch()
{
_properties = GetPropertyFunctions<T>().ToList();
}
public bool Match(T item, string searchTerm)
{
bool match = _properties.Select(prop => prop(item)).Any(value => value != null && value.ToLower().Contains(searchTerm.ToLower()));
return match;
}
}
答案 1 :(得分:1)
将属性设为私有字段,并在首次使用时使用Lazy Wrapper对其进行初始化。 你必须让其他方法静态才能像这样使用它,但这应该很容易实现。
private Lazy<IEnumerable<Func<T, string>>> properties = new Lazy<IEnumerable<Func<T, string>>>(GetPropertyFunctions<T>);
public bool Match<T>(T item, string searchTerm)
{
bool match = properties.Value.Select(prop => prop(item)).Any(value => value != null && value.ToLower().Contains(searchTerm.ToLower()));
return match;
}