我是反思的新手,请原谅我的noob问题。如何创建一个带有两个参数的方法,一个通用列表和一个字符串,然后查找该列表中任何属性值与字符串匹配的所有项目。
因此,例如,我们有一个具有3个属性的对象,我将此对象的列表传递给方法和搜索字符串,并返回一个对象列表,其中任何属性可能包含搜索字符串。
我可以这样做:
var temp = list.AsQueryable().Where("SomeField == 1").Select("it");
但是我怎样才能使这个方法Generic,所以我可以将任何对象列表传递给它?
提前致谢...
答案 0 :(得分:1)
使用Type.GetProperties()
获取对象的所有属性。使用PropertyInfo.GetValue()
获取给定对象中给定属性的值。您需要弄清楚如何将字符串与DateTime,数字或其他复杂对象进行匹配。把它全部放到像bool IsMatch(this object obj, string val)
这样的函数中。然后,您可以像list.Where(x => x.IsMatch("something"))
一样过滤您的列表。
答案 1 :(得分:1)
你在这里交配:
private static void Main(string[] args)
{
var list = new List<object> {new {prop1 = "A", prop2 = "B"},new {prop3 = "B", prop4 = "C"}};
var subList = SearchForStringInProperties(list, "C");
}
private static IEnumerable<object> SearchForStringInProperties(IEnumerable<object> list, string searchString)
{
return from obj in list where FindStringInObjProperties(obj, searchString) select obj;
}
private static bool FindStringInObjProperties(object obj, string searchString)
{
return obj.GetType().GetProperties().Any(property => obj.GetType().GetProperty(property.Name).GetValue(obj).ToString().Equals(searchString));
}
答案 2 :(得分:1)
如果您使用的是Dynamic Linq,请尝试使用
public static IEnumerable<T> Filter<T>(IEnumerable<T> source, string searchStr)
{
var propsToCheck = typeof (T).GetProperties().Where(a => a.PropertyType == typeof(string));
var filter = propsToCheck.Aggregate(string.Empty, (s, p) => (s == string.Empty ? string.Empty : string.Format("{0} OR ", s)) + string.Format("{0} == @0", p.Name));
var filtered = source.AsQueryable().Where(filter, searchStr);
return filtered;
}
答案 3 :(得分:0)
如果您只想匹配与您的参数类型相同的属性,则此扩展方法可以提供帮助,
public static class ListExtensions
{
public static IEnumerable<T> MatchWithAnyProperty<T, TK>(this IEnumerable<T> list, TK value)
{
var argType = typeof (TK);
var properties = typeof(T).GetProperties().Where(x => x.PropertyType.IsAssignableFrom(argType));
return list.Where(item => properties.Any(prop =>
{
var propertyValue = prop.GetValue(item, null);
if (value == null)
return propertyValue == null;
return propertyValue.Equals(value);
}));
}
}
这可以像
一样使用var items = new[]
{
new
{
Name = "Test",
Age = 20,
Test=25
},
new
{
Name = "Hello",
Age = 10,
Test=15
},
new
{
Name = "T2gdhest",
Age = 14,
Test=20
},
new
{
Name = "hai",
Age = 33,
Test=10
},
new
{
Name = "why not",
Age = 10,
Test=33
},
};
var match= items.MatchWithAnyProperty(10);
foreach (var item in match)
{
Console.WriteLine(item.Name);
}
Console.ReadKey();
答案 4 :(得分:0)
还有旧方法......
public static IList<T> MyMethod<T>(IList<T> myList, string filter)
{
if (myList == null) return null;
if (filter == null) return myList;
var tfilter = filter.GetType();
var properties = typeof(T).GetProperties().Where(x => x.PropertyType.FullName == typeof(string).FullName);
if (!properties.Any()) return null;
var res = new List<T>();
foreach(var el in myList)
{
foreach(var p in properties)
{
if ((string)p.GetValue(el) == filter)
{
res.Add(el);
break;
}
}
}
return res;
}