使用linq从IEnumerable中排除类型

时间:2012-02-01 14:45:49

标签: c# linq linq-to-objects

如何使用linq-to-objects基于派生类型过滤掉对象?

我正在寻找性能最佳的解决方案。

使用的课程:

abstract class Animal { }
class Dog : Animal { }
class Cat : Animal { }
class Duck : Animal { }
class MadDuck : Duck { }

我知道三种方法:使用is关键字,使用Except方法,并使用OfType方法。

List<Animal> animals = new List<Animal>
{
    new Cat(),
    new Dog(),
    new Duck(),
    new MadDuck(),
};

// Get all animals except ducks (and or their derived types)
var a = animals.Where(animal => (animal is Duck == false));
var b = animals.Except((IEnumerable<Animal>)animals.OfType<Duck>());

// Other suggestions
var c = animals.Where(animal => animal.GetType() != typeof(Duck))

// Accepted solution
var d = animals.Where(animal => !(animal is Duck));

4 个答案:

答案 0 :(得分:9)

如果你想排除Duck的子类,那么is是最好的。您可以将代码缩短为.Where(animal => !(animal is Duck));

否则,sll对GetType的推荐是最好的

答案 1 :(得分:4)

  • 使用Except()的解决方案非常繁重。
  • 请注意,解决方案is - 即使从SomeDuck

    继承的Duck类也会返回true
    class SomeDuck : Duck
    ...
    // duck is Duck == true
    var duck = new SomeDuck();
    

另一种解决方案可能是:

animals.Where(animal => animal.GetType() != typeof(Duck))

答案 2 :(得分:3)

根据Difference between OfType<>() and checking type in Where() extension,OfType调用等同于您的选项(a),虽然是Duck == true ,所以基于此我会说坚持选项(a)

答案 3 :(得分:1)

如果您不希望返回DuckDuck的任何子类,则需要使用IsAssignableFrom方法:

animals.Where(animal => !animal.GetType().IsAssignableFrom(typeof(Duck)));