簡體   English   中英

如何遞歸搜索對象列表中的字符串項

[英]How to recursively search for string term in a list of obects

我正在嘗試實現一種方法,用於搜索某個搜索詞的對象列表,然后返回這些對象。

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

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;
}

ObjectExtensions

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中崩潰,並顯示以下消息:

該應用程序處於中斷模式

您的應用已進入中斷狀態,但是由於所有線程都在執行外部代碼(通常是系統代碼或框架代碼),因此沒有任何代碼可顯示。

我以前從未見過這樣的錯誤,但是我懷疑它與運行到無限循環中的代碼有關,因為它正在檢查對象的屬性,然后檢查那些屬性的屬性,等等-在那里停止?

有人對我如何實現這一目標有任何建議嗎?

謝謝

您的遞歸調用檢查property對象是否包含word ,而不是原始對象上的屬性值是否包含單詞。

更改

result = property.Contains(word);

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

我的最終解決方案如下所示

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");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM