如何检查基类列表是否包含所有指定子类的实例?
嘿,这个需求很好实现,我给你两种实用的方案,你可以根据自己的场景来选:
方案1:使用Type参数(灵活支持任意数量类型)
这种方式最灵活,能支持传入任意数量的类型,不需要提前定义重载:
using System.Collections.Generic; using System.Linq; public class YourClass { public bool ContainsAllRequiredTypes(List<BaseClass> childClasses, params Type[] requiredTypes) { // 处理空列表/空参数的边界情况 if (childClasses == null) throw new ArgumentNullException(nameof(childClasses)); if (requiredTypes == null || requiredTypes.Length == 0) return true; // 如果你觉得无需求时应该返回false,可以改成return false // 收集列表中已存在的所有类型(去重,因为只要有一个实例就满足) var existingTypes = childClasses.Select(element => element.GetType()).ToHashSet(); // 检查所有传入的类型是否都存在于列表的类型集合中(精确匹配) return requiredTypes.All(type => existingTypes.Contains(type)); } }
用法示例:
// 检查列表是否同时包含ChildFoo和ChildBar的实例 bool hasAll = yourClassInstance.ContainsAllRequiredTypes(ChildClasses, typeof(ChildFoo), typeof(ChildBar));
如果你需要支持「派生类实例也算匹配」:
比如列表里有ChildFoo的子类GrandChildFoo,传入typeof(ChildFoo)也希望返回true,只需要把判断逻辑改成:
return requiredTypes.All(type => childClasses.Any(element => type.IsAssignableFrom(element.GetType())));
方案2:泛型重载(类型安全,编译时检查)
如果你希望在编译时就确保传入的类型都是BaseClass的派生类,避免传错类型,可以用泛型重载的方式:
using System.Collections.Generic; using System.Linq; public class YourClass { // 支持1种类型 public bool ContainsAllTypes<T1>(List<BaseClass> childClasses) where T1 : BaseClass { if (childClasses == null) throw new ArgumentNullException(nameof(childClasses)); return childClasses.Any(e => e is T1); } // 支持2种类型 public bool ContainsAllTypes<T1, T2>(List<BaseClass> childClasses) where T1 : BaseClass where T2 : BaseClass { if (childClasses == null) throw new ArgumentNullException(nameof(childClasses)); return childClasses.Any(e => e is T1) && childClasses.Any(e => e is T2); } // 按需添加更多重载(比如支持3种、4种类型) public bool ContainsAllTypes<T1, T2, T3>(List<BaseClass> childClasses) where T1 : BaseClass where T2 : BaseClass where T3 : BaseClass { if (childClasses == null) throw new ArgumentNullException(nameof(childClasses)); return childClasses.Any(e => e is T1) && childClasses.Any(e => e is T2) && childClasses.Any(e => e is T3); } }
用法示例:
// 检查列表是否同时包含ChildFoo和ChildBar的实例 bool hasAll = yourClassInstance.ContainsAllTypes<ChildFoo, ChildBar>(ChildClasses);
一些注意事项
- 空列表处理:两种方案都加了
childClasses为null的异常抛出,你可以根据自己的需求改成返回false或者其他逻辑。 - 类型匹配精度:
e is T和type.IsAssignableFrom(element.GetType())会把派生类实例也算作匹配,而element.GetType() == typeof(T)或existingTypes.Contains(type)是精确匹配原类型。 - 重复类型参数:如果传入重复的类型(比如两次传
typeof(ChildFoo)),方案1可以通过requiredTypes.Distinct().All(...)来避免重复检查,提升效率。
内容的提问来源于stack exchange,提问作者starikcetin
相关产品推荐
相关产品推荐

