[英]How to recursively search for string term in a list of obects
我正在嘗試實現一種方法,用於搜索某個搜索詞的對象列表,然后返回這些對象。
到目前為止,如果搜索詞包含在對象的任何字符串屬性中,我就可以使其正常工作:
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中崩潰,並顯示以下消息:
該應用程序處於中斷模式
您的應用已進入中斷狀態,但是由於所有線程都在執行外部代碼(通常是系統代碼或框架代碼),因此沒有任何代碼可顯示。
我以前從未見過這樣的錯誤,但是我懷疑它與運行到無限循環中的代碼有關,因為它正在檢查對象的屬性,然后檢查那些屬性的屬性,等等-在那里停止?
有人對我如何實現這一目標有任何建議嗎?
謝謝
您的遞歸調用檢查property
對象是否包含word
,而不是原始對象上的屬性值是否包含單詞。
更改
result = property.Contains(word);
至
result = property.GetValue(inuputObject, null).Contains(word);
我的最終解決方案如下所示
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;
}
}
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.