代码之家  ›  专栏  ›  技术社区  ›  S. Tarık Çetin

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

c#
  •  0
  • S. Tarık Çetin  · 技术社区  · 6 年前

    我有这样一个基类列表:

    List<BaseClass> ChildClasses
    

    我有这样的儿童课程:

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

    我需要实现一个可以查询 ChildClasses 列表以查看它是否具有我传递给它的所有类型,这些类型都是从 BaseClass

    因此,如果我为类型调用此方法 ChildFoo ChildBar ,如果 儿童班 列表至少包含一个 儿童食品 儿童酒吧

    我如何处理这种情况?

    3 回复  |  直到 6 年前
        1
  •  5
  •   Igor    6 年前

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

    你可以使用 OfType 具有 Any 。然后可以多次组合表达式。

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

    候补

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

    Type[] mandatoryTypes = new Type[] {typeof(ChildFoo), typeof(ChildBar)};
    var containsFooAndBar = mandatoryTypes.All(mandatoryType => ChildClasses.Any(instance => instance != null && mandatoryType == instance.GetType()));
    
        2
  •  1
  •   Sean Reid    6 年前

    假设继承层次结构没有比您的示例更深。。。

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

    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来构造哈希集),并且对于子类或所需类型中的大量项,这种方法应该更容易实现。

        3
  •  1
  •   ThePerplexedOne    6 年前

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

        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));