我有一个像这样的基类列表:
List<BaseClass> ChildClasses
我有这样的子课:
class ChildFoo : BaseClass {}
class ChildBar : BaseClass {}
class ChildBaz : BaseClass {}
class ChildQax : BaseClass {}
class ChildBox : BaseClass {}
...
我需要实现一个方法,该方法可以查询ChildClasses
列表,看看它是否包含我传递给它的所有类型,这些类型都来自BaseClass
。
因此,如果我为类型ChildFoo
和ChildBar
调用此方法,如果ChildClasses
列表包含至少一个ChildFoo
和{{1}的实例,则它应返回true }}
我如何处理这种情况?
答案 0 :(得分:5)
如果ChildClasses列表包含至少一个ChildFoo和ChildBar实例,它应该返回true。
您可以将OfType与Any一起使用。然后,您可以多次组合表达式。
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));