我有一个通用列表。我必须根据列表项的属性值过滤列表。直到运行时才知道项类型。
我必须通过反射找到项目类型,然后需要过滤。
请以任何想法或示例帮助我
感谢。
答案 0 :(得分:1)
如果列表是通用的,那么应该在编译时至少知道一个基类型。
如果基类型包含属性 - 只需使用它。
如果只有部分子类型(理想情况是一个)包含您感兴趣的属性,则可以在列表中执行cast,然后使用您的属性。
list.Cast<Derived>().Select(i => i.Property == "val");
如果这不好(比如列表的类型有很多包含属性的派生类型而其他类型没有),你可以使用带有try / catch块的动态。
list.Select(i => {
try
{
dynamic item = i;
return item.Prop == "value";
}
catch(RuntimeBinderException) //this type doesn't contain the property
{
return false;
}
});
答案 1 :(得分:1)
我希望这个帮助
传递任何列表,并指定属性名称和过滤方法
private IList FilterList(IList list, string propName, Predicate<object> filterMethod) {
var result = new List<object>();
foreach (var item in list) {
var value = item.GetType().GetProperty(propName).GetValue(item);
if (filterMethod(value)) {
result.Add(item);
}
}
return result;
}
示例:
var result = FilterList(list, "Age", age => (int)age >= 18);
你可以开发它并使它充满活力
答案 2 :(得分:0)
试试这个。它可以确定List是否是某些指定类型的列表。基于此,您应该能够过滤任何特定类型。
public class TypeA
{ }
public class TypeB
{ }
public class GenericFilter
{
public bool IsOfType<T>(IEnumerable<dynamic> objectToInspect)
{
var genericType = objectToInspect.GetType().GenericTypeArguments[0];
return genericType == typeof(T);
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void IdentifiesExpectedType()
{
var classToInspect = new List<TypeA>();
var filter = new GenericFilter();
Assert.IsTrue(filter.IsOfType<TypeA>(classToInspect));
}
[TestMethod]
public void RejectsNonMatchingType()
{
var classToInspect = new List<TypeA>();
var filter = new GenericFilter();
Assert.IsFalse(filter.IsOfType<TypeB>(classToInspect));
}
}
这同样有效:
public bool IsOfType<T>(IEnumerable<dynamic> listToFilter)
{
return (listToFilter as IEnumerable<T>) != null;
}
这将获取列表列表并将它们分组到Dictionary<Type, List<List<dynamic>>
,其中每个键的所有列表都属于该类型。这样,您只需从字典中检索它们就可以选择类型T的列表。
public Dictionary<Type, List<List<dynamic>>> GroupListsByType(List<List<dynamic>> lists)
{
var types = lists.Select(list => list.GetType().GenericTypeArguments[0]).Distinct().ToList();
var grouped = new Dictionary<Type, List<List<dynamic>>>();
types.ForEach(type =>
{
grouped.Add(type, new List<List<dynamic>>());
grouped[type].AddRange(lists.Where(list=>list.GetType().GenericTypeArguments[0] == type));
});
return grouped;
}
(我不是在质疑“为什么。”我不知道我是否会推荐这个,但写起来很有意思。)