如何检查基类型列表是否至少包含一些子类型的实例

时间:2018-03-22 10:58:00

标签: c#

我有一个像这样的基类列表:

List<BaseClass> ChildClasses

我有这样的子课:

class ChildFoo : BaseClass {}
class ChildBar : BaseClass {}
class ChildBaz : BaseClass {}
class ChildQax : BaseClass {}
class ChildBox : BaseClass {}
...

我需要实现一个方法,该方法可以查询ChildClasses列表,看看它是否包含我传递给它的所有类型,这些类型都来自BaseClass

因此,如果我为类型ChildFooChildBar调用此方法,如果ChildClasses列表包含至少一个ChildFoo和{{1}的实例,则它应返回true }}

我如何处理这种情况?

3 个答案:

答案 0 :(得分:5)

  

如果ChildClasses列表包含至少一个ChildFoo和ChildBar实例,它应该返回true。

您可以将OfTypeAny一起使用。然后,您可以多次组合表达式。

var containsFooAndBar = ChildClasses.OfType<ChildFoo>().Any() 
                     && ChildClasses.OfType<ChildBar>().Any();

交替

你也可以从另一个方向接近它。创建需要包含的所有必需类型的列表,然后使用ChildClasses列表作为输入在该列表上执行查询。这只是编写上述内容的另一种方式,ChildClasses集合仍然迭代超过2倍。

Type[] mandatoryTypes = new Type[] {typeof(ChildFoo), typeof(ChildBar)};
var containsFooAndBar = mandatoryTypes.All(mandatoryType => ChildClasses.Any(instance => instance != null && mandatoryType == instance.GetType()));

答案 1 :(得分:1)

假设继承层次结构没有比你的例子更深入......

在列表中创建实际类型的哈希集:

var actualTypes= new HashSet<Type>(ChildClasses.Select(x=>x.GetType()));

然后创建所需类型的哈希集:

var requiredTypes = new HashSet<Type>
        {
            typeof(ChildFoo),
            typeof(ChildBar)
        };

从所需类型集中删除所有实际类型:

requiredTypes.ExceptWith(actualTypes);

如果requiredTypes.Count == 0,则列表包含所有必需的类型。如果requiredTypes.Count > 0则缺少类型,这些类型将保留为requiredTypes的内容。

如果所需类型的数量是可变的(让调用者直接传入哈希集或从中构造哈希集的IEnumerable),并且对于ChildClasses中的大量项目或者需要,那么这种方法应该更容易实现类型。

答案 2 :(得分:1)

您可以创建一个方法来获取类列表以及类型数组,然后检查提供的列表是否包含所有这些类型:

    static bool ContainsTypes(List<BaseClass> list, params Type[] types)
    {
        return types.All(type => list.Any(x => x != null && type == x.GetType()));
    }

并按照以下方式实施:

    List<BaseClass> baseClasses = new List<BaseClass>();
    baseClasses.Add(new ChildFoo());
    baseClasses.Add(new ChildBar());
    //Population code here...
    var result = ContainsTypes(baseClasses, typeof(ChildFoo), typeof(ChildBar));

或者如果您想使用扩展方法

public static class Extensions
{
    public static bool ContainsTypes(this List<BaseClass> list, params Type[] types)
    {
        return types.All(type => list.Any(x => x != null && type == x.GetType()));
    }
}

再一次,实施如下:

List<BaseClass> baseClasses = new List<BaseClass>();
baseClasses.Add(new ChildFoo());
baseClasses.Add(new ChildBar());
//Population code here...
var result = baseClasses.ContainsTypes(typeof(ChildFoo), typeof(ChildBar));