检查列表是否包含特定类型(多个)

时间:2015-06-18 10:28:16

标签: c# linq

我有一段代码检查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。有点像白名单方法。关于我如何做到这一点的任何想法?

4 个答案:

答案 0 :(得分:4)

你可以做到以下几点(如果有错误的话,我会因为我们在午餐时间附近因为脆皮培养而担心这种偏见):

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

答案 1 :(得分:1)

嗯......培根...

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

答案 2 :(得分:0)

这样的事情:

        var bacon = new List<Bacon>();

        bacon
            .GroupBy(_ => _.GetType())
            .Select(_ => _.FirstOrDefault())
            .ToList();

答案 3 :(得分:0)

您是否只想要每种类型的第一次出现?如果是这样,我想你可以这样做:

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

希望它有所帮助!

编辑:修复了编译问题。只要没有培根的子类,这就应该有效。