如何通过c#中的反射过滤通用列表

时间:2016-04-03 08:09:59

标签: c# .net reflection

我有一个通用列表。我必须根据列表项的属性值过滤列表。直到运行时才知道项类型。

我必须通过反射找到项目类型,然后需要过滤。

请以任何想法或示例帮助我

感谢。

3 个答案:

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

(我不是在质疑“为什么。”我不知道我是否会推荐这个,但写起来很有意思。)