猿问

如何递归搜索对象列表中的字符串项

我正在尝试实现一种方法,用于搜索某个搜索词的对象列表,然后返回这些对象。


到目前为止,如果搜索词包含在对象的任何字符串属性中,我就可以使其正常工作:


IEnumerableExtensions

public static IEnumerable<T> Search<T>(this IEnumerable<T> items, string search)

{

    if (!string.IsNullOrEmpty(search))

        items = items.Where(i => i.Contains(search));


    return items;

}

对象扩展

public static bool Contains(this object inuputObject, string word)

{

    return inuputObject.GetType()

            .GetProperties()

            .Where(x => x.PropertyType == typeof(string))

            .Select(x => (string)x.GetValue(inuputObject, null))

            .Where(x => x != null)

            .Any(x => x.IndexOf(word, StringComparison.CurrentCultureIgnoreCase) >= 0);

}

问题是,我正在搜索的对象都包含一个user对象列表,并且我想在搜索中包括这些用户的字符串属性。


我尝试了这个:


public static bool Contains(this object inuputObject, string word)

{

    var result = false;


    var type = inuputObject.GetType();

    var properties = type.GetProperties();


    foreach (var property in properties)

    {

        if (property.PropertyType == typeof(string) && property != null)

        {

            var propertyValue = (string)property.GetValue(inuputObject, null);

            result = propertyValue.IndexOf(word, StringComparison.CurrentCultureIgnoreCase) >= 0;

        }

        else

        {

            result = property.Contains(word);

        }


        if (result)

            break;

    }


    return result;

}

但是我认为这是围绕我不感兴趣的属性进行迭代的,它会导致程序在VS中崩溃,并显示以下消息:


该应用程序处于中断模式


您的应用已进入中断状态,但由于所有线程都在执行外部代码(通常是系统代码或框架代码),因此没有要显示的代码。


我以前从未见过这样的错误,但是我怀疑它与运行到无限循环中的代码有关,因为它正在检查对象的属性,然后是这些属性的属性,等等-到哪里停止? ?


有人对我如何实现这一目标有任何建议吗?


12345678_0001
浏览 194回答 2
2回答

子衿沉夜

您的递归调用检查property对象是否包含word,而不是原始对象上该属性的值是否包含单词。改变result&nbsp;=&nbsp;property.Contains(word);至result&nbsp;=&nbsp;property.GetValue(inuputObject,&nbsp;null).Contains(word);

神不在的星期二

我的最终解决方案如下所示ObjectExtensions.cspublic static class ObjectExtensions{&nbsp; &nbsp; /// <summary>&nbsp; &nbsp; /// Checks each string property of the given object to check if it contains the&nbsp;&nbsp; &nbsp; /// search term. If any of those properties is a collection, we search that&nbsp;&nbsp; &nbsp; /// collection using the the IEnumarableExtensions Search&nbsp; &nbsp; /// </summary>&nbsp; &nbsp; /// <param name="inputObject"></param>&nbsp; &nbsp; /// <param name="term"></param>&nbsp; &nbsp; /// <returns></returns>&nbsp; &nbsp; public static bool Contains(this object inputObject, string term)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var result = false;&nbsp; &nbsp; &nbsp; &nbsp; if (inputObject == null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return result;&nbsp; &nbsp; &nbsp; &nbsp; var properties = inputObject&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .GetType()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .GetProperties();&nbsp; &nbsp; &nbsp; &nbsp; foreach (var property in properties)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // First check if the object is a string (and ensure it is not null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (property != null && property.PropertyType == typeof(string))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var propertyValue = (string)property.GetValue(inputObject, null);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = propertyValue == null&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? false&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : propertyValue.IndexOf(term,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StringComparison.CurrentCultureIgnoreCase) >= 0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Otherwise, check if its a collection (we need to do this after the string&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // check, as a string is technically a IEnumerable type&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = ((IEnumerable<object>)property&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .GetValue(inputObject, null))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Search(term).Count() > 0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var propertyValue = property.GetValue(inputObject, null);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result = propertyValue == null&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? false&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : propertyValue.ToString().Contains(term);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (result)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return result;&nbsp; &nbsp; }}IEnumerableExtensions.cspublic static class IEnumerableExtensions{&nbsp; &nbsp; /// <summary>&nbsp; &nbsp; /// Extension method that searches a list of generic objects' string properties&nbsp;&nbsp; &nbsp; /// for the given search term using the 'Contains' object extension&nbsp; &nbsp; /// </summary>&nbsp; &nbsp; /// <typeparam name="T"></typeparam>&nbsp; &nbsp; /// <param name="items"></param>&nbsp; &nbsp; /// <param name="search"></param>&nbsp; &nbsp; /// <returns></returns>&nbsp; &nbsp; public static IEnumerable<T> Search<T>(this IEnumerable<T> items, string search)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (!string.IsNullOrEmpty(search))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; items = items.Where(i => i.Contains(search));&nbsp; &nbsp; &nbsp; &nbsp; return items;&nbsp; &nbsp; }}用法因此,要在对象集合中搜索某些字符串:var list = new List<MyType>(){};var results = list.Search("searchTerm");
随时随地看视频慕课网APP
我要回答