为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
12345678_0001 2021-04-07 13:14:12
我正在尝试实现一种方法,用于搜索某个搜索词的对象列表,然后返回这些对象。到目前为止,如果搜索词包含在对象的任何字符串属性中,我就可以使其正常工作:IEnumerableExtensionspublic 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中崩溃,并显示以下消息:该应用程序处于中断模式您的应用已进入中断状态,但由于所有线程都在执行外部代码(通常是系统代码或框架代码),因此没有要显示的代码。我以前从未见过这样的错误,但是我怀疑它与运行到无限循环中的代码有关,因为它正在检查对象的属性,然后是这些属性的属性,等等-到哪里停止? ?有人对我如何实现这一目标有任何建议吗?
查看完整描述

2 回答

?
子衿沉夜

TA贡献1828条经验 获得超3个赞

您的递归调用检查property对象是否包含word,而不是原始对象上该属性的值是否包含单词。

改变

result = property.Contains(word);

result = property.GetValue(inuputObject, null).Contains(word);


查看完整回答
反对 回复 2021-04-24
?
神不在的星期二

TA贡献1963条经验 获得超6个赞

我的最终解决方案如下所示


ObjectExtensions.cs

public static class ObjectExtensions

{

    /// <summary>

    /// Checks each string property of the given object to check if it contains the 

    /// search term. If any of those properties is a collection, we search that 

    /// collection using the the IEnumarableExtensions Search

    /// </summary>

    /// <param name="inputObject"></param>

    /// <param name="term"></param>

    /// <returns></returns>

    public static bool Contains(this object inputObject, string term)

    {

        var result = false;


        if (inputObject == null)

            return result;


        var properties = inputObject

            .GetType()

            .GetProperties();


        foreach (var property in properties)

        {

            // First check if the object is a string (and ensure it is not null)

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

            {

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

                result = propertyValue == null

                    ? false

                    : propertyValue.IndexOf(term, 

                        StringComparison.CurrentCultureIgnoreCase) >= 0;

            }

            // Otherwise, check if its a collection (we need to do this after the string  

            // check, as a string is technically a IEnumerable type

            else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))

            {

                result = ((IEnumerable<object>)property

                    .GetValue(inputObject, null))

                    .Search(term).Count() > 0;

            }

            else

            {

                var propertyValue = property.GetValue(inputObject, null);

                result = propertyValue == null

                    ? false

                    : propertyValue.ToString().Contains(term);

            }


            if (result)

                break;

        }


        return result;

    }

}

IEnumerableExtensions.cs

public static class IEnumerableExtensions

{

    /// <summary>

    /// Extension method that searches a list of generic objects' string properties 

    /// for the given search term using the 'Contains' object extension

    /// </summary>

    /// <typeparam name="T"></typeparam>

    /// <param name="items"></param>

    /// <param name="search"></param>

    /// <returns></returns>

    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;

    }

}

用法

因此,要在对象集合中搜索某些字符串:


var list = new List<MyType>(){};

var results = list.Search("searchTerm");


查看完整回答
反对 回复 2021-04-24
  • 2 回答
  • 0 关注
  • 190 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信