我有一个代码块,它检查List
的派生类型,然后将第一个实例添加到另一个List
。
var bacon = new List<Bacon>(); // A list of all bacon products
var selectedBacon = new List<Bacon>();
var smokey= bacon.FirstOrDefault(x => x is Smokey);
if (smokey != null)
{
selectedBacon.Add(smokey);
}
var rasher = bacon.FirstOrDefault(x => x is Rasher);
if (rasher != null)
{
selectedBacon.Add(rasher);
}
随着类型数量的增加,此方法开始变得很长。
问题
我希望能够将其重构为可以检查多个类型的 Linq 语句并将第一项添加到新List
中。 有点像白名单方法。 关于我如何做到这一点的任何想法?
你可以执行以下操作(如果有错别字,我责怪我们在接近午餐时间时对脆皮培根的偏心想法):
var types = new List<Type>
{
typeof(Smokey),
typeof(Rasher),
typeof(Danish)
};
如注释中所述,对于培根列表中的每个项目,您希望从类型中第一个匹配的相应类型:
List<Type> selectedBaconTypes = bacon
.Select(b => types.FirstOrDefault(t => b.GetType().Equals(t.GetType())))
.Where(b => b != null)
.ToList();
嗯...培根。。。
var types = new List<Type>
{
typeof(Smokey),
typeof(Rasher),
typeof(Danish)
};
var bacon = new List<Bacon>();
// ..
var selectedBacon = new List<Bacon>();
if (types.Count != 0)
{
// We clone it
var types2 = types.ToList();
foreach (var b in bacon)
{
var btype = b.GetType();
// A bacon could be of multiple "types" thanks to subclassing
while (true)
{
// The IsAssignableFrom is equivalent to the is operator
int ix = types.FindIndex(x => x.IsAssignableFrom(btype));
if (ix != -1)
{
selectedBacon.Add(b);
types2.RemoveAt(ix);
}
else
{
break;
}
}
if (types2.Count == 0)
{
break;
}
}
}
请注意使用 IsAssignableFrom
而不是使用 GetType()
。这样,您可以拥有class SmokeyPlusCheese : Smokey
。
像这样:
var bacon = new List<Bacon>();
bacon
.GroupBy(_ => _.GetType())
.Select(_ => _.FirstOrDefault())
.ToList();
你只想要每种类型的第一次出现吗?如果是这样,我想你可以做这样的事情:
var types = new List<Type>
{
typeof(Smokey),
typeof(Rasher),
typeof(Danish)
};
foreach(var b in bacon) {
if (types.Any(t => b.GetType() == t)) {
selectedBacon.Add(b);
types.Remove(b.GetType());
}
if (types.Count == 0) {
break;
}
}
希望对您有所帮助!
编辑:修复了编译问题。只要没有培根的子类,这应该有效。