如何根据派生类字段过滤基类集合?

时间:2013-05-22 20:31:35

标签: c# linq inheritance

假设我有一个名为MyThings的集合,它包含类Thing的对象,我有一个名为ShinyThing的类,它是从Thing派生的,所以我做:

MyThings boxWithMyThings = new MyThings();
ShinyThing Diamond = new ShinyThing(){ facets =  10; weight = 500 };
boxWithMyThings.Add(Diamond);

如何使用派生类的属性过滤集合boxWithMyThings

2 个答案:

答案 0 :(得分:4)

想必你只想要ShinyThings?如果是,请使用OfType

// I'm assuming MyThings implements IEnumerable<MyThing>
var heavyShinyThings = boxWithMyThings.OfType<ShinyThing>()
                                      .Where(x => x.weight > 100);

答案 1 :(得分:2)

只要OfType实施boxWithMyThings,您就可以尝试使用IEnumerable<Thing>方法:

var filtered = boxWithMyThings.OfType<ShingThing>().Where(st => st.facets == 10);

如果您想要过滤多种类型(不只是ShinyThings,您可以将Concat与许多类似的来电一起使用:

IEnumerable<Thing> shinyEnough = boxWithMyThings.OfType<ShingThing>().Where(st => st.shininess >= 10);
IEnumerable<Thing> dirtyEnough = boxWithMyThings.OfType<DirtyThing>().Where(dt => dt.dirtiness >= 10);
var veryDirtyAndVeryCleanObjects = shinyEnough.Concat(dirtyEnough); 

当然,您可以通过检查类型和转换来将所有Where谓词放在一个大Where子句中,这可能不太可读但效率更高:

boxWithMyThings.Where(t =>  
     { 
         if (t is ShinyThing) 
                return (t as ShinyThing).shininess >= 10;
         else if (t is DirtyThing) 
                return (t as DirtyThing).dirtiness >= 10; 
         else return false;
     });