使用带有不同类型/类列表的泛型方法

时间:2015-02-02 15:36:10

标签: c# list generics

我正在尝试为List构建搜索功能。这很简单,但是我想要一个方法,它可以采用不同类型的列表。以下面的示例来清除问题:

方法SearchGridViewCategorie和SearchGridViewMedewerker都是搜索List的方法,如果它包含搜索词。

public static void SearchGridViewMedewerker(ref List<Medewerker> medewerkers, String term) {
    medewerkers = medewerkers.Where(m => m.gebruikersnaam.ToLower().Contains(term.ToLower()) ||
                    m.naam.ToLower().Contains(term.ToLower()) ||
                    m.email.ToLower().Contains(term.ToLower()) ||
                    m.rol.ToLower().Contains(term.ToLower())).ToList();
}

public static void SearchGridViewCategorie(ref List<Categorie> categorieen, String term) {
    categorieen = categorieen.Where(c => c.omschrijving.ToLower().Contains(term.ToLower())).ToList();
}

我试图使这个搜索方法通用,这样我就可以将不同类型的列表传递给同一个方法。我尝试过以下方法:

public static List<object> SearchGridView(List<object> list, String term) {
    IList<PropertyInfo> properties = list.GetType().GetProperties().ToList();
    List<object> tempList = new List<object>();

        foreach(object o in list){
            foreach (var property in properties) {
                if (property.ToString().Contains(term.ToLower())) {
                    tempList.Add(o);
                }
            }
        }
    return tempList;
}

然而,使用此解决方案,我必须在方法中传递List之前将类型T的List转换为对象列表。

这不是我想要的。我想传递任何类型的List,处理它并返回一个已作为参数给出的类型的List。这可能吗?

2 个答案:

答案 0 :(得分:2)

我认为这就是你的意思:

public static IList<T> SearchGridView<T>(IList<T> list, String term) 
{
    IList<PropertyInfo> properties = typeof(T).GetProperties();
    var t = term.ToLower();
    return list
        .Where(item =>
            properties
                .Select(p => p.GetValue(item).ToString())
                .Any(v => v.Contains(t)))
        .ToList();
}

答案 1 :(得分:1)

看起来你正试图简化这种性质的代码:

x => x.property.ToLower().Contains(term.ToLower())

其中属性是字符串属性, term 是您要搜索的文本。如果是这样,您可以使用LINQ扩展方法来执行此操作:

public static class Extensions
{
    public static IEnumerable<T> WhereTextInProperties<T>(this IEnumerable<T> source,
        string searchText, params Func<T, string>[] getPropertyValues)
    {
        searchText = searchText.ToLowerInvariant();

        return from element in source
               from getPropertyValue in getPropertyValues
               let propertyValue = getPropertyValue(element)
               where propertyValue.ToLowerInvariant().Contains(searchText)
               select element;
    }
}

然后你会像这样使用它:

return medewerkers.WhereTextInProperties(term,
    m => m.gebruikersnaam, m => m.naam,
    m => m.email, m => m.rol
    );

您可以通过各种不同的方式(正则表达式,表达式列表而不是函数委托等)来改进它,但它可以作为起点。